企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持知识库和私有化部署方案 广告
[TOC] 在TCP/IP协议中“IP地址 + TCP或UDP端口号”作为唯一标识网络通讯中的一个进程,“IP + 端口号”就称为socket。在TCP协议中,建立连接的两个进程各自有一个socket来标识,那么两个socket组成的socket pair就唯一标识一个连接。 ## 相关函数 与网络通信相关的几个函数: * [socket](https://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html):创建一个socket; * [bind](https://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html#):将socket绑定到端口上; * [listen](https://pubs.opengroup.org/onlinepubs/9699919799/functions/listen.html#): 开始监听端口; * [accept](https://pubs.opengroup.org/onlinepubs/9699919799/functions/accept.html#):取出等待链接队列中的首元素; * [connect](https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html#):与指定ip端口创建连接; * [close](https://pubs.opengroup.org/onlinepubs/9699919799/functions/close.html#):关闭连接; ## 创建socket ```c++ // 创建socket并监控指定ip和端口 static int create_socket(const char* ip, int port) { int sock = socket(AF_INET, SOCK_STREAM, 0); // 创建socket if (sock < 0) { perror("failed to create socket"); return -1; } sockaddr_in local; // 设置监听端口配置 local.sin_family = AF_INET; local.sin_port = htons(port); local.sin_addr.s_addr = inet_addr(ip); // 将socket绑定到端口上 if (bind(sock, (struct sockaddr*)&local, sizeof(local)) < 0) { close(sock); perror("failed to bind socket"); return -1; } // socket开始监听端口 static int BACK_LOG = 10; if (listen(sock, BACK_LOG) < 0) { close(sock); perror("failed to listen socket"); return -1; } return sock; } ``` ## 建立连接 server 端: ```c++ #include <algorithm> #include <arpa/inet.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <unistd.h> int main(int argc, char** argv) { if (argc != 3) { return -1; } int sock = create_socket(argv[1], atoi(argv[2])); if (sock < 0) { printf("failed to create socket"); return -1; } printf("start to listen ip[%s:%s]\n", argv[1], argv[2]); sockaddr_in link; socklen_t sz = sizeof(link); int fd = accept(sock, (struct sockaddr*)&link, &sz); if (fd < 0) { perror("failed to accept"); close(sock); return -1; } printf("fd = %d\n", fd); static const int MAX_READ_SIZE = 1024; char buffer[MAX_READ_SIZE]; while (1) { ssize_t s = read(fd, buffer, sizeof(buffer) - 1); printf("recv message: %s", buffer); if (s > 0) { const char* msg = "HTTP/1.0 200 OK\n"; write(fd, msg, strlen(msg)); } else if (s == 0) { printf("fd[%d] quit\n", fd); close(fd); break; } else { perror("failed to read fd"); close(fd); break; } } printf("sock[%d] quit\n", sock); close(sock); return 0; } ``` client端: ```c++ #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <unistd.h> #include <netinet/in.h> #include <arpa/inet.h> #include <stdlib.h> #include <string.h> int main(int argc, char** argv) { if (argc != 3) { printf("FATAL: no host or port"); exit(1); } int sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) { perror("failed to create socket"); return 1; } struct sockaddr_in server; server.sin_family = AF_INET; server.sin_addr.s_addr = inet_addr(argv[1]); server.sin_port = htons(atoi(argv[2])); if (connect(sock, (struct sockaddr *)&server, sizeof(server)) < 0) { perror("failed to connect"); exit(1); } while (1) { printf("send message: "); fflush(stdout); static const int MAX_BUFF_SIZE = 1024; char buffer[MAX_BUFF_SIZE]; ssize_t s = read(0, buffer, sizeof(buffer) - 1); if (s > 0) { buffer[s] = '\0'; } write(sock, buffer, strlen(buffer)); s = read(sock, buffer, sizeof(buffer) - 1); if(s > 0) { buffer[s - 1] = 0; printf("server feeback: %s\n", buffer); } } close(sock); return 0; } ``` ## 相关文献 - [opengroup-socket](https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html)