套接字通信

发布时间:2026/9/11 18:58:33
套接字通信 为什么服务器端要bind客户端不要服务器先建立需要给他绑定一个确切的IP和端口这样客户端发送数据才知道发送给哪个。至于客户端connect时候已经创建了一个随机的临时源端口ephemeral port / 动态端口同时使用本机合适的网卡 IP 作为源 I关于文件描述符服务端监听1个通信n个客户端通信1个P。实现多进程网络通信一个服务端端可以和好几个客户端连接在accept处设置循环每accept一个创建一个新线程管理接受的客户端#include sys/types.h #include sys/socket.h #include stdio.h #include stdlib.h #include unistd.h #include string.h #include arpa/inet.h #includepthread.h //因为worker函数要传入客户端ip端口所以要把fd和struct sockaddr_in封装在一起 struct SocketInfo { struct sockaddr_in addr; int cfd; }; struct SocketInfo infos[512]; void* working(void* arg); int main() { //创建监听的套接字 int lfd socket(AF_INET, SOCK_STREAM, 0); if (lfd -1) { perror(socket); return -1; } struct sockaddr_in addr; addr.sin_family AF_INET; addr.sin_port htons(5000);//转化成大端端口 addr.sin_addr.s_addr INADDR_ANY; inet_pton(AF_INET, 192.168.204.128, addr.sin_addr.s_addr); //绑定本地端口和IP int ret bind(lfd, (struct sockaddr*)addr, sizeof(addr)); if (ret -1) { perror(bind); exit(0); } //设置监听 int l listen(lfd, 128); if (l -1) { perror(listen); exit(0); } // 4. 阻塞等待并接受客户端连接 printf(wait kehu....\n); //// 初始化结构体数组全部置0fd-1代表空闲 int max sizeof(infos) / sizeof(infos[0]); for (int i 0; i max; i) { bzero(infos[i], sizeof(infos[i])); infos[i].cfd -1; } //每接受到一个创建一个线程 while (1) { struct SocketInfo* m_info; //找寻数组中没有被占用的 for (int i 0; i max; i) { if (infos[i].cfd -1) { m_info infos[i]; break; } } socklen_t clilen sizeof(sockaddr_in); int cfd accept(lfd, (struct sockaddr*)m_info-addr, clilen);//cfd用于通信的文件描述符 if (cfd -1) { perror(accept); exit(0); } m_info-cfd cfd; //创建子线程 pthread_t tid; pthread_create(tid, NULL, working, m_info); pthread_detach(tid); } return 0; } void* working(void* arg) { //打印客户端信息 //客户端 IP 保存在 cliaddr.sin_addr.s_addr struct SocketInfo* infos (struct SocketInfo*)arg; char ip[24]; printf(kehu ip:%s,kehu endpoint: %d\n, inet_ntop(AF_INET, infos-addr.sin_addr.s_addr, ip, sizeof(ip)), ntohs(infos-addr.sin_port)); //和用户通信 while (1) { //接受数据 char buf[1024]; memset(buf, 0, sizeof(buf)); int len read(infos-cfd, buf, sizeof(buf)); if (len 0) { printf(kehu say: %s\n, buf); write(infos-cfd, buf, len); } else if (len 0) { printf(kehu cut connect\n); break; } else { perror(read); break; } } close(infos-cfd); infos-cfd -1;//置为空闲 return NULL; }// client.c #include stdio.h #include stdlib.h #include unistd.h #include string.h #include arpa/inet.h int main() { //创建通信套接字 int fd socket(AF_INET, SOCK_STREAM, 0); if (fd -1) { perror(socket); exit(0); } //连接服务器 struct sockaddr_in addr; addr.sin_family AF_INET; addr.sin_port htons(5000); inet_pton(AF_INET, 192.168.204.128, addr.sin_addr.s_addr); int ret connect(fd, (struct sockaddr*)addr, sizeof(addr)); if (ret -1) { perror(connect); exit(0); } int num 0; while (1) { //发送数据 char buf[1024]; sprintf(buf, hello fuwuqi%d\n, num); write(fd, buf, strlen(buf) 1); //接收数据 memset(buf, 0, sizeof(buf)); int len read(fd, buf, sizeof(buf)); if (len 0) { printf(fuwuqi say %s\n, buf); } else if (len 0) { printf(fuwuqi duankai..\n); break; } else { perror(read); break; } sleep(1); } return 0; }