C中实现TCP套接字
发布日期:2021-05-15 00:46:39 浏览次数:26 分类:精选文章

本文共 9461 字,大约阅读时间需要 31 分钟。

如何在C中实现TCP套接字

最近一直出差,大家不好意思。文章更新的有点慢,希望大家包涵!!谢谢!!!今天讲工业现在用到最多的通讯协议。

TCP套接字用于服务器和客户端进程之间的通信。服务器的代码首先运行,这将打开一个端口并侦听来自客户端的传入连接请求。客户端连接到相同的(服务器)端口后,客户端或服务器可能会发送一条消息。邮件一旦发送,接收者(服务器或客户端)将对其进行相应处理。

服务器端

#include 
#include
#include
#include
int main(void){ int socket_desc, client_sock, client_size; struct sockaddr_in server_addr, client_addr; char server_message[2000], client_message[2000]; // Clean buffers: memset(server_message, '\0', sizeof(server_message)); memset(client_message, '\0', sizeof(client_message)); // Create socket: socket_desc = socket(AF_INET, SOCK_STREAM, 0); if(socket_desc < 0){ printf("Error while creating socket\n"); return -1; } printf("Socket created successfully\n"); // Set port and IP: server_addr.sin_family = AF_INET; server_addr.sin_port = htons(2000); server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); // Bind to the set port and IP: if(bind(socket_desc, (struct sockaddr*)&server_addr, sizeof(server_addr))<0){ printf("Couldn't bind to the port\n"); return -1; } printf("Done with binding\n"); // Listen for clients: if(listen(socket_desc, 1) < 0){ printf("Error while listening\n"); return -1; } printf("\nListening for incoming connections.....\n"); // Accept an incoming connection: client_size = sizeof(client_addr); client_sock = accept(socket_desc, (struct sockaddr*)&client_addr, &client_size); if (client_sock < 0){ printf("Can't accept\n"); return -1; } printf("Client connected at IP: %s and port: %i\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); // Receive client's message: if (recv(client_sock, client_message, sizeof(client_message), 0) < 0){ printf("Couldn't receive\n"); return -1; } printf("Msg from client: %s\n", client_message); // Respond to client: strcpy(server_message, "This is the server's message."); if (send(client_sock, server_message, strlen(server_message), 0) < 0){ printf("Can't send\n"); return -1; } // Closing the socket: close(client_sock); close(socket_desc); return 0;}

解释

包括头文件sys/socket.h和arpa/inet.h:

#include 
#include

创建一个返回套接字描述符的套接字;稍后将在代码中使用它来引用套接字:

int socket_desc = socket(AF_INET, SOCK_STREAM, 0);

的服务器端代码保持在所述服务器和类型的变量的客户机两者的地址信息sockaddr_in,这是一个struct。

通过端口和IP初始化服务器地址:

struct sockaddr_in server_addr;server_addr.sin_family = AF_INET;server_addr.sin_port = htons(2000);server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");

将套接字描述符绑定到服务器地址:

bind(socket_desc, (struct sockaddr*)&server_addr, sizeof(server_addr);

打开套接字以侦听传入的连接:

listen(socket_desc, 1);

通过接受传入的连接来存储客户端的地址和套接字描述符:

struct sockaddr client_addr;int client_size = sizeof(client_addr);int client_sock = accept(socket_desc, (struct sockaddr*)&client_addr, &client_size);

服务器端代码停止并等待,accept()直到客户端调用connect()。

使用send()和与客户进行沟通recv():

recv(client_sock, client_message, sizeof(client_message), 0);send(client_sock, server_message, strlen(server_message), 0);

当recv()被调用时,代码停止并等待来自客户端的消息。

关闭服务器和客户端套接字以结束通信:

close(client_sock);close(socket_desc);

客户端

#include 
#include
#include
#include
int main(void){ int socket_desc; struct sockaddr_in server_addr; char server_message[2000], client_message[2000]; // Clean buffers: memset(server_message,'\0',sizeof(server_message)); memset(client_message,'\0',sizeof(client_message)); // Create socket: socket_desc = socket(AF_INET, SOCK_STREAM, 0); if(socket_desc < 0){ printf("Unable to create socket\n"); return -1; } printf("Socket created successfully\n"); // Set port and IP the same as server-side: server_addr.sin_family = AF_INET; server_addr.sin_port = htons(2000); server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); // Send connection request to server: if(connect(socket_desc, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0){ printf("Unable to connect\n"); return -1; } printf("Connected with server successfully\n"); // Get input from the user: printf("Enter message: "); gets(client_message); // Send the message to server: if(send(socket_desc, client_message, strlen(client_message), 0) < 0){ printf("Unable to send message\n"); return -1; } // Receive the server's response: if(recv(socket_desc, server_message, sizeof(server_message), 0) < 0){ printf("Error while receiving server's msg\n"); return -1; } printf("Server's response: %s\n",server_message); // Close the socket: close(socket_desc); return 0;}

解释

包括头文件,创建套接字,并使用类型为的变量初始化服务器的地址信息sockaddr_in,类似于在服务器端进行的操作:

#include 
#include
int socket_desc = socket(AF_INET, SOCK_STREAM, 0);struct sockaddr_in server_addr;server_addr.sin_family = AF_INET;server_addr.sin_port = htons(2000);server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");

向服务器发送连接请求,该服务器正在等待accept():

connect(socket_desc, (struct sockaddr*)&server_addr, sizeof(server_addr));

使用send()和与服务器通信recv():

send(socket_desc, client_message, strlen(client_message),0);recv(socket_desc, server_message, sizeof(server_message),0);

客户端在recv()被调用时等待服务器发送消息。

关闭插座:

close(socket_desc);

如果客户端和服务器都在处等待对方的消息,则会发生死锁recv()。

在这里插入图片描述

客户端-服务器应用

以下客户端服务器应用程序使客户端可以连接到服务器并仅发送一条消息。服务器回复“这是服务器的消息”,并且通信终止。

指示

1、单击下面的小部件中的“运行”按钮,然后执行服务器的命令。如果成功创建了套接字,将显示消息“正在侦听传入的连接…”。
2、按下+按钮以打开另一个终端标签并执行客户端的命令。
3、在“客户端”选项卡中输入一条消息,该消息将发送到服务器。
4、该服务器的响应将在显示客户小号标签”。
在这里插入图片描述
TCP_Server.c

#include 
#include
#include
#include
int main(void){ int socket_desc, client_sock, client_size; struct sockaddr_in server_addr, client_addr; char server_message[100], client_message[100]; // Clean buffers: memset(server_message, '\0', sizeof(server_message)); memset(client_message, '\0', sizeof(client_message)); // Create socket: socket_desc = socket(AF_INET, SOCK_STREAM, 0); if(socket_desc < 0){ printf("Error while creating socket\n"); return -1; } printf("Socket created successfully\n"); // Set port and IP: server_addr.sin_family = AF_INET; server_addr.sin_port = htons(2000); server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); // Bind to the set port and IP: if(bind(socket_desc, (struct sockaddr*)&server_addr, sizeof(server_addr))<0){ printf("Couldn't bind to the port\n"); return -1; } printf("Done with binding\n"); // Listen for clients: if(listen(socket_desc, 1) < 0){ printf("Error while listening\n"); return -1; } printf("\nListening for incoming connections.....\n"); // Accept an incoming connection: client_size = sizeof(client_addr); client_sock = accept(socket_desc, (struct sockaddr*)&client_addr, &client_size); if (client_sock < 0){ printf("Can't accept\n"); return -1; } printf("Client connected at IP: %s and port: %i\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); // Receive client's message: if (recv(client_sock, client_message, sizeof(client_message), 0) < 0){ printf("Couldn't receive\n"); return -1; } printf("Msg from client: %s\n", client_message); // Respond to client: strcpy(server_message, "This is the server's message."); if (send(client_sock, server_message, strlen(server_message), 0) < 0){ printf("Can't send\n"); return -1; } // Closing the socket: close(client_sock); close(socket_desc); return 0;}

TCP_client.c

#include 
#include
#include
#include
int main(void){ int socket_desc; struct sockaddr_in server_addr; char server_message[100], client_message[100]; // Clean buffers: memset(server_message,'\0',sizeof(server_message)); memset(client_message,'\0',sizeof(client_message)); // Create socket: socket_desc = socket(AF_INET, SOCK_STREAM, 0); if(socket_desc < 0){ printf("Unable to create socket\n"); return -1; } printf("Socket created successfully\n"); // Set port and IP the same as server-side: server_addr.sin_family = AF_INET; server_addr.sin_port = htons(2000); server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); // Send connection request to server: if(connect(socket_desc, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0){ printf("Unable to connect\n"); return -1; } printf("Connected with server successfully\n"); // Get input from the user: printf("Enter message: "); gets(client_message); // Send the message to server: if(send(socket_desc, client_message, strlen(client_message), 0) < 0){ printf("Unable to send message\n"); return -1; } // Receive the server's response: if(recv(socket_desc, server_message, sizeof(server_message), 0) < 0){ printf("Error while receiving server's msg\n"); return -1; } printf("Server's response: %s\n",server_message); // Close the socket: close(socket_desc); return 0;}

关注苏州程序大白,持续更新技术分享。谢谢大家支持

上一篇:C#中的群集, 泛型和计时类
下一篇:8种提升程序猿编程能力的方法+编程思维四个核心:分解、抽象、模式识别和算法

发表评论

最新留言

路过按个爪印,很不错,赞一个!
[***.219.124.196]2025年04月24日 23时42分28秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章