Programmation réseau en langage C (2) - Communication TCP

Programmation réseau en langage C (2) - Communication TCP

1. Client TCP

1. Etablir la connexion
Nous voulons utiliser le socket, tout d'abord, nous ajoutons d'abord le fichier d'en-tête à utiliser

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

Créez un socket tcp, protocole ipv4, utilisez le paramètre SOCK_STREAM, le protocole est 0, il sélectionnera automatiquement le protocole tcp par défaut;

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

Ensuite, nous mettons l'adresse IP et le numéro de port du serveur dans une structure pour préparer

    // 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地址

Utilisez ensuite la méthode connect pour vous connecter, si la connexion réussit, elle renvoie 0. L'échec renvoie -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);

Enfin, n'oubliez pas de fermer le socket

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

Compiler et exécuter, la connexion est réussie:
Insérez la description de l'image ici
Insérez la description de l'image ici
2, envoyer des données
Utilisez la fonction send () pour envoyer des données

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

On peut voir que les données ont été envoyées avec succès, le serveur a reçu les données
Insérez la description de l'image ici
3.
Si les données doivent être reçues, vous pouvez utiliser la fonction recv pour attendre la réception. Son paramètre est le nombre maximal d'octets reçus, puis les données reçues sont imprimées. Sortez
Insérez la description de l'image ici
Insérez la description de l'image ici

Le code complet est le suivant:

#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);
}

Deuxièmement, le serveur TCP

1. Etablissez le serveur et attendez la connexion.
De même, nous voulons utiliser le socket. Tout d'abord, nous ajoutons le fichier d'en-tête à utiliser.

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

Créez un socket tcp, protocole ipv4, utilisez le paramètre SOCK_STREAM, le protocole est 0, il sélectionnera automatiquement le protocole tcp par défaut;

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

Pour que le client s'y connecte, nous devons lier un numéro de port

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

Ensuite, nous pouvons utiliser la méthode listen pour écouter les connexions. Le deuxième paramètre est le nombre de connexions en file d'attente que nous pouvons attendre

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

Utilisez la méthode accept pour attendre que le client se connecte à ce serveur, la valeur de retour est le descripteur de fichier de socket client connecté

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

Nous imprimons les informations client qui y sont liées

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

Ensuite, nous pouvons fermer la prise

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

Exécutez le programme et connectez-vous à l'aide de l'assistant de débogage réseau. Vous pouvez voir que la connexion est réussie.
Insérez la description de l'image ici
Insérez la description de l'image ici
2. Recevoir des données.
Lorsqu'un client se connecte, nous pouvons utiliser le descripteur de fichier de socket client pour attendre les données envoyées par l'autre partie.

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

Compiler, exécuter et utiliser le client assistant de débogage réseau pour envoyer des données. Les résultats sont les suivants:
Insérez la description de l'image ici
3. Envoyer des données Après avoir
reçu les données, nous renvoyons les données pour informer le client que j'ai reçu les données

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

Compiler et exécuter le résultat
Insérez la description de l'image ici
Code complet

#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);
}
Publié 68 articles originaux · gagné 13 · vues 5723

Je suppose que tu aimes

Origine blog.csdn.net/qq_38113006/article/details/105539262
conseillé
Classement