下面分别以TCP、UDP为例介绍两者的流程图和代码实现:
- TCP
1.流程图:
和网上大部分的版本不同,我将TCP三次握手的过程画在了accpet之前,这也是在查阅一些资料发现三次握手会由内核自动完成,aceept只是从队列中取出已经建好的tcp连接,这一点可以在accept之前多加点等待时间验证。
2.代码实现:
server端:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <arpa/inet.h> #define SERVER_PORT 8888 #define SERVER_IP "192.168.1.100" int main() { // 1. 创建监听套接字 int fd = socket(AF_INET, SOCK_STREAM, 0); if (fd == -1) { perror("fail fo socket!"); return -1; } printf("create socket fd[%d] success!\n"); // 2. 绑定监听套接字到本地IP和port struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_port = htons(SERVER_PORT); inet_pton(AF_INET, SERVER_IP, &addr.sin_addr); int ret = bind(fd, (struct sockaddr*)&addr, sizeof(addr)); if (ret == -1) { perror("fail to bind!"); return -2; } printf("bind success!\n"); // 3. 设置监听 ret = listen(fd, 128); if (ret == -1) { perror("fail to listen!"); return -3; } printf("listen success!\n"); // 4. 阻塞等待,等待连接到达,连接成功后返回通信用的套接字 struct sockaddr_in c_addr; int c_addr_len = 0; int c_fd = accept(fd, (struct sockaddr*)&c_addr, &c_addr_len); if (c_fd == -1) { perror("fail to accept!"); return -4; } printf("accept success!\n"); // 5. 开始通信 char buff[1024]; char ip[32]; memset(buff, 0, sizeof(buff)); memset(ip, 0, sizeof(ip)); int len = read(c_fd, buff, sizeof(buff)); if (len > 0) { printf("client %s:%d >> %s\n", inet_ntop(AF_INET, &c_addr.sin_addr, ip , sizeof(ip)), ntohs(c_addr.sin_port), buff); write(c_fd, buff, len); } else if (len == 0) { printf("connect close!"); } else { printf("connect fail!"); } // 6. 关闭套接字 close(fd); close(c_fd); return 0; }
client端:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <arpa/inet.h> #define SERVER_PORT 8888 #define SERVER_IP "192.168.1.100" int main() { // 1. 创建通信套接字 int fd = socket(AF_INET, SOCK_STREAM, 0); if (fd == -1) { perror("fail fo socket!"); return -1; } printf("create socket success!\n"); // 2. 连接服务器 struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_port = htons(SERVER_PORT); inet_pton(AF_INET, SERVER_IP, &addr.sin_addr); int ret = connect(fd, (struct sockaddr*)&addr, sizeof(addr)); if (fd == -1) { perror("fail to connect!"); return -2; } printf("connect success!\n"); // 3. 通信 char buff[1024]; char ip[32]; sprintf(buff, "Hello, this is a test connection with the server!"); int len = send(fd, buff, strlen(buff) + 1, 0); memset(buff, 0, sizeof(buff)); memset(ip, 0, sizeof(ip)); len = recv(fd, buff, sizeof(buff), 0); if (len > 0) { printf("server %s:%d >> %s\n", inet_ntop(AF_INET, &addr.sin_addr, ip , sizeof(ip)), ntohs(addr.sin_port), buff); } else if (len == 0) { printf("connect close!\n"); } else { perror("recv fail!\n"); } // 4. 关闭套接字 close(fd); return 0; }