Programação de rede em linguagem C (2) - comunicação TCP

Programação de rede em linguagem C (2) - comunicação TCP

1. cliente TCP

1. Estabeleça a conexão
Queremos usar o soquete, antes de tudo, primeiro adicionamos o arquivo de cabeçalho a ser usado

#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <unistd.h>

Crie um soquete tcp, protocolo ipv4, use o parâmetro SOCK_STREAM, o protocolo é 0, ele selecionará automaticamente o protocolo tcp por padrão;

    // 1、使用socket()函数获取一个socket文件描述符
	int tcp_client = socket(AF_INET, SOCK_STREAM, 0);

Em seguida, colocamos o endereço IP e o número da porta do servidor em uma estrutura para preparar

    // 2、准备服务端的地址和端口,'192.168.0.107'表示目的ip地址,12341表示目的端口号
    struct sockaddr_in server_addr = {0};	
	server_addr.sin_family = AF_INET;                           // 设置地址族为IPv4
	server_addr.sin_port = htons(12341);						// 设置地址的端口号信息
	server_addr.sin_addr.s_addr = inet_addr("192.168.0.107");	// 设置IP地址

Em seguida, use o método connect para conectar, se a conexão for bem-sucedida, ela retornará 0. A falha retornará -1

    // 3、链接到服务器
    ret = connect(tcp_client, (const struct sockaddr *)&server_addr, sizeof(server_addr));
    if (ret < 0)
		perror("connect");
    else
	    printf("connect result, ret = %d.\n", ret);

Por fim, lembre-se de fechar o soquete

    // 4、关闭套接字
    close(tcp_client);

Compile e execute, a conexão foi bem-sucedida:
Insira a descrição da imagem aqui
Insira a descrição da imagem aqui
2, envie dados
Use a função send () para enviar dados

    // 4. 发送数据到服务端
	char sendbuf[]={"hello world."};
	ret = send(sockfd, sendbuf, strlen(sendbuf),0);

Pode-se observar que os dados foram enviados com sucesso, o servidor recebeu os dados
Insira a descrição da imagem aqui
3.
Se os dados forem recebidos, você poderá usar a função recv para aguardar a recepção.O parâmetro é o número máximo de bytes recebidos e os dados recebidos são impressos. Sair
Insira a descrição da imagem aqui
Insira a descrição da imagem aqui

O código completo é o seguinte:

#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <unistd.h>

int main(void)
{
    int ret;
    // 1、使用socket()函数获取一个TCP客户端socket文件描述符
	int tcp_client = socket(AF_INET, SOCK_STREAM, 0);
    if (-1 == tcp_client)
	{
		perror("socket");
		return -1;
	}

    // 2、准备服务端的地址和端口,'192.168.0.107'表示目的ip地址,12341表示目的端口号
    struct sockaddr_in server_addr = {0};	
	server_addr.sin_family = AF_INET;                           // 设置地址族为IPv4
	server_addr.sin_port = htons(12341);						// 设置地址的端口号信息
	server_addr.sin_addr.s_addr = inet_addr("192.168.0.107");	// 设置IP地址

    // 3、链接到服务器
    ret = connect(tcp_client, (const struct sockaddr *)&server_addr, sizeof(server_addr));
    if (ret < 0)
		perror("connect");
    else
	    printf("connect result, ret = %d.\n", ret);

    // 4. 发送数据到服务端
	char sendbuf[]={"hello world."};
	ret = send(tcp_client, sendbuf, strlen(sendbuf),0);

    // 5、等待接收服务端发送过来的数据,最大接收1024个字节
    char recvbuf[1024] = {0};
    ret = recv(tcp_client, recvbuf, sizeof(recvbuf), 0);

    // 6、将接收到的数据打印出来
    printf("Recvdate:%s \n",recvbuf);

    // 7、关闭套接字
    close(tcp_client);
}

Segundo, o servidor TCP

1. Estabeleça o servidor e aguarde a conexão.
Da mesma forma, queremos usar o soquete. Primeiro, adicionamos o arquivo de cabeçalho a ser usado.

#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <unistd.h>

Crie um soquete tcp, protocolo ipv4, use o parâmetro SOCK_STREAM, o protocolo é 0, ele selecionará automaticamente o protocolo tcp por padrão;

    // 1、使用socket()函数获取一个socket文件描述符
	int tcp_server = socket(AF_INET, SOCK_STREAM, 0);

Para que o cliente se conecte a ele, precisamos vincular um número de porta

    // 2. 绑定本地的相关信息,如果不绑定,则系统会随机分配一个端口号
    struct sockaddr_in local_addr = {0};
    local_addr.sin_family = AF_INET;		                    // 设置地址族为IPv4
	local_addr.sin_port = htons(8266);	                        // 设置地址的端口号信息
	local_addr.sin_addr.s_addr = inet_addr("192.168.0.107");	// 设置IP地址
	ret = bind(tcp_server, (const struct sockaddr *)&local_addr, sizeof(local_addr));
	if (ret < 0)
		perror("bind");
    else	
        printf("bind success.\n");

Em seguida, podemos usar o método listen para ouvir conexões.O segundo parâmetro é o número de conexões em fila pelas quais podemos esperar

    // 3、listen监听端口,阻塞,等待客户端来连接服务器
	ret = listen(sockfd, 5);

Use o método accept para aguardar a conexão do cliente com este servidor, o valor de retorno é o descritor do arquivo de soquete do cliente conectado

    // 4、accept阻塞等待客户端接入
    struct sockaddr_in client_addr;
    socklen_t addrlen = sizeof(client_addr);
	int client_fd = accept(tcp_server, (struct sockaddr *)&client_addr, &addrlen);

Imprimimos as informações do cliente vinculadas a ele

    // 5、打印连接过来的客户端信息及其ip地址
    printf("Client from %s:%d \n",inet_ntoa(*(struct in_addr*)&client_addr.sin_addr.s_addr),ntohs(client_addr.sin_port));

Então podemos fechar o soquete

     // 6、关闭套接字
    close(tcp_client);

Execute o programa e conecte-se usando o assistente de depuração de rede.Você pode ver que a conexão foi bem-sucedida
Insira a descrição da imagem aqui
Insira a descrição da imagem aqui
2. Receber dados
Quando um cliente se conecta, podemos usar o descritor de arquivo de soquete do cliente para aguardar os dados enviados pela outra parte.

// 5、等待接收对方发送过来的数据
    char recvbuf[1024] = {0};
    ret = recv(client_fd, recvbuf, sizeof(recvbuf), 0);
    printf("Recv from %s:%d, ",inet_ntoa(*(struct in_addr*)&client_addr.sin_addr.s_addr),ntohs(client_addr.sin_port));
    printf("recv_data: %s \n",recvbuf);

Compile, execute e use o cliente assistente de depuração de rede para enviar dados.Os resultados são os seguintes:
Insira a descrição da imagem aqui
3. Enviar dados Depois de
receber os dados, enviamos os dados de volta para informar ao cliente que os recebi.

    // 6、返回数据到客户端
    char send_buf[1024] = "I have got the date:";
    strcat(send_buf,recvbuf);
    send(client_fd, send_buf, strlen(send_buf), 0);

Compile e execute o resultado
Insira a descrição da imagem aqui
Código completo

#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <unistd.h>

int main(void)
{
    int ret = -1;
    // 1、使用socket()函数获取一个socket文件描述符
	int tcp_server = socket(AF_INET, SOCK_STREAM, 0);
    if (-1 == tcp_server)
	{
		perror("socket");
		return -1;
	}

    // 2. 绑定本地的相关信息,如果不绑定,则系统会随机分配一个端口号
    struct sockaddr_in local_addr = {0};
    local_addr.sin_family = AF_INET;		                    // 设置地址族为IPv4
	local_addr.sin_port = htons(8266);	                        // 设置地址的端口号信息
	local_addr.sin_addr.s_addr = inet_addr("192.168.0.107");	// 设置IP地址
	ret = bind(tcp_server, (const struct sockaddr *)&local_addr, sizeof(local_addr));
	if (ret < 0)
		perror("bind");
    else	
        printf("bind success.\n");

    // 3、listen监听端口,阻塞,等待客户端来连接服务器
	ret = listen(tcp_server, 5);

    // 4、accept阻塞等待客户端接入
    struct sockaddr_in client_addr;
    socklen_t addrlen = sizeof(client_addr);
	int client_fd = accept(tcp_server, (struct sockaddr *)&client_addr, &addrlen);

    // 5、等待接收对方发送过来的数据
    char recvbuf[1024] = {0};
    ret = recv(client_fd, recvbuf, sizeof(recvbuf), 0);
    printf("Recv from %s:%d, ",inet_ntoa(*(struct in_addr*)&client_addr.sin_addr.s_addr),ntohs(client_addr.sin_port));
    printf("recv_data: %s \n",recvbuf);

    // 6、返回数据到客户端
    char send_buf[1024] = "I have got the date:";
    strcat(send_buf,recvbuf);
    send(client_fd, send_buf, strlen(send_buf), 0);

     // 7、关闭套接字
    close(tcp_server);
}
Publicado 68 artigos originais · ganhou 13 · visualizações 5723

Acho que você gosta

Origin blog.csdn.net/qq_38113006/article/details/105539262
Recomendado
Clasificación