Linux下使用多线程模拟异步网络通信
服务器
/* socket server * 2014-12-15 CopyRight (c) arbboter */ #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <time.h> #include <sys/socket.h> #include <sys/types.h> #include <netdb.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> #include <vector> using namespace std; vector<int> vecClient; // 线程同步锁 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; void* recv_thr(void*p); void* send_thr(void*p); int main() { int sockfd_server; int sockfd_client; struct sockaddr_in addr_server; struct sockaddr_in addr_client; socklen_t addr_len = 0; int client_max = 10; int server_port = 33891; srand(time(NULL)); // create socket sockfd_server = socket(AF_INET, SOCK_STREAM, 0); if(sockfd_server == -1) { printf("init socket failed\n"); return -1; } // set address memset(&addr_server, 0, sizeof(addr_server)); addr_server.sin_family = AF_INET; addr_server.sin_addr.s_addr = htonl(INADDR_ANY); addr_server.sin_port = htons(server_port); // socket bind with address if(bind(sockfd_server, (struct sockaddr*)&addr_server, sizeof(struct sockaddr)) == -1) { printf("bind socket failed\n"); return -1; } // server socket start list, waitting client to connect // 这个client_max是指同时连接数 if(listen(sockfd_server, client_max) == -1) { printf("start listen socket failed\n"); return -1; } // 数据线程 pthread_t tid = 0; pthread_create(&tid, NULL, send_thr, NULL); while(1) { addr_len = sizeof(struct sockaddr_in); printf("waitting for connected...\n"); // waitting for connected sockfd_client = accept(sockfd_server, (struct sockaddr*)&addr_client, &addr_len); if(sockfd_client == -1) { printf("accept socket failed\n"); return -1; } // create a thread to talk with client printf("recived connection from : %s\n", inet_ntoa(addr_client.sin_addr)); pthread_create(&tid, NULL, recv_thr, (void*)&sockfd_client); // 加到发数据对象集合中 pthread_mutex_lock(&mutex); vecClient.push_back(sockfd_client); pthread_mutex_unlock(&mutex); } close(sockfd_server); pthread_mutex_destroy(&mutex); return 0; } // 收数据 void* recv_thr(void*p) { int fd = *((int*)p); int nRead = 0; char szBuf[512] = {0}; while(1) { memset(szBuf, 0, sizeof(szBuf)); nRead = read(fd, szBuf, sizeof(szBuf)); printf("client : %s\n", szBuf); if(strcmp(szBuf, "quit") == 0) { break; } sprintf(szBuf, "Your magic number is : %d", rand()%100); printf("server : %s\n", szBuf); write(fd, szBuf, strlen(szBuf)); } return NULL; } // 发数据 void* send_thr(void*p) { size_t i = 0; char szBuf[512] = {0}; while(1) { sleep(rand()%10); pthread_mutex_lock(&mutex); for(int i=0; i<vecClient.size(); i++) { sprintf(szBuf, "Your magic number is : %d", rand()%100); printf("[%02d] server : %s\n", i, szBuf); write(vecClient[i], szBuf, strlen(szBuf)); } pthread_mutex_unlock(&mutex); } return NULL; }
客户端
/* socket client * 2014-12-15 CopyRight (c) arbboter */ #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <sys/socket.h> #include <sys/types.h> #include <netdb.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> #include <signal.h> #include <errno.h> #include <string.h> void* recv_thr(void*p); int main() { int sockfd_server; struct sockaddr_in addr_server; socklen_t addr_len = 0; int server_port = 33891; char* server_addr = "192.168.2.200"; // create socket sockfd_server = socket(AF_INET, SOCK_STREAM, 0); if(sockfd_server == -1) { printf("init socket failed\n"); return -1; } // set server address memset(&addr_server, 0, sizeof(addr_server)); addr_server.sin_family = AF_INET; addr_server.sin_addr.s_addr = inet_addr(server_addr);; addr_server.sin_port = htons(server_port); // connect server if(connect(sockfd_server,(struct sockaddr *)&addr_server,sizeof(struct sockaddr))==-1) { printf("connect server failed\n"); return -1; } // 启动收数据线程 pthread_t tid = 0; pthread_create(&tid, NULL, recv_thr, (void*)&sockfd_server); // 发送数据 char szBuf[512] = {0}; int nLen = 0; while(1) { // 收线程已退出 if( ESRCH == pthread_kill(tid,0) ) { break; } // 等待输入数据 gets(szBuf); nLen = strlen(szBuf); if(nLen > 0) { szBuf[nLen] = '\0'; write(sockfd_server, szBuf, nLen); } } close(sockfd_server); return 0; } // 收数据 void* recv_thr(void*p) { int fd = *((int*)p); int nRead = 0; char szBuf[512] = {0}; while(1) { memset(szBuf, 0, sizeof(szBuf)); nRead = read(fd, szBuf, sizeof(szBuf)); printf("server : %s\n", szBuf); if(strcmp(szBuf, "quit") == 0) { break; } } return NULL; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)