Programación de red en lenguaje C (2) -Comunicación TCP

Programación de red en lenguaje C (2) -Comunicación TCP

1. cliente TCP

1. Establecer la conexión
Queremos usar el socket, en primer lugar, primero agregamos el archivo de encabezado que se usará

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

Cree un socket tcp, protocolo ipv4, use el parámetro SOCK_STREAM, el protocolo es 0, seleccionará automáticamente el protocolo tcp por defecto;

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

Luego colocamos la dirección IP y el número de puerto del servidor en una estructura 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地址

Luego use el método de conexión para conectarse, si la conexión es exitosa, devuelve 0. Falla devuelve -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);

Finalmente, recuerde cerrar el zócalo

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

Compile y ejecute, la conexión es exitosa:
Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí
2, envíe datos
Use la función enviar () para enviar datos

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

Se puede ver que los datos se han enviado correctamente, el servidor ha recibido los datos
Inserte la descripción de la imagen aquí
3.
Si se van a recibir los datos , puede usar la función recv para esperar la recepción. Su parámetro es el número máximo de bytes recibidos, y luego se imprimen los datos recibidos. Sal
Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí

El código completo es el siguiente:

#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, el servidor TCP

1. Establezca el servidor y espere la conexión.
Del mismo modo, queremos usar el socket. Primero, agregamos el archivo de encabezado que se utilizará.

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

Cree un socket tcp, protocolo ipv4, use el parámetro SOCK_STREAM, el protocolo es 0, seleccionará automáticamente el protocolo tcp por defecto;

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

Para que el cliente se conecte a él, debemos vincular un número de puerto

    // 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");

Entonces podemos usar el método de escucha para escuchar las conexiones. El segundo parámetro es el número de conexiones en cola que podemos esperar

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

Use el método accept para esperar a que el cliente se conecte a este servidor, el valor de retorno es el descriptor del archivo de socket del 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 la información del cliente vinculada a ella

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

Entonces podemos cerrar el zócalo

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

Ejecute el programa y conéctese utilizando el asistente de depuración de la red. Puede ver que la conexión es exitosa.
Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí
2. Recibir datos.
Cuando un cliente se conecta, podemos usar el descriptor de archivo de socket del cliente para esperar los datos enviados por la otra 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, ejecute y use el cliente asistente de depuración de red para enviar datos. Los resultados son los siguientes:
Inserte la descripción de la imagen aquí
3. Enviar datos Después de
recibir los datos, los enviamos de vuelta para informarle al cliente que los he recibido.

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

Compila y ejecuta el resultado
Inserte la descripción de la imagen aquí
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 artículos originales · ganó 13 · vistas 5723

Supongo que te gusta

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