TCP/IPC语言实现单个客户端和服务端TCP通信
- 开源代码
- 2025-08-04 03:54:01

这是多线程服务端
#include <stdio.h> #include <winsock2.h> #include <pthread.h> #include <string.h> #include <conio.h> #pragma comment(lib,"ws2_32.lib") #pragma warning(disable : 4996) // 客户端结构体 typedef struct ThreadNode { int index; pthread_t* Thread; SOCKET Client; struct ThreadNode * next; ThreadNode() { index = 0; this->next = NULL; } } hThread; // 增加客户端结构体 hThread *clientHeadNote, *clientEndNote; hThread * addClient() { hThread * ClientNote = new hThread(); return ClientNote; } // 每个建立链接的客户端分配一个函数,每个线程运行一个这样的函数 void* ThreadClient(void*) { if (clientEndNote == NULL) { printf("empty Link\n"); return 0; } char revData[255]; SOCKET sClient = clientEndNote->Client; printf("client logged in \n"); while (1) { int ret = recv(sClient, revData, 255, 0); // 接收数据 if (ret > 0) { revData[ret] = 0x00; printf(revData); printf("\n"); if (strcmp("log_out", revData) == 0) // 新功能:加入客户端控制签退 { char a[255]; strcpy(a, "已注销\n"); send(sClient, a, 255, 0); // 反馈:向客户端sClienr发送“已注销”消息,发送长度为255个字节,1是指不阻塞。 closesocket(sClient); printf("签退成功\n"); } else { char a[255]; strcpy(a, "服务器已收到消息\n"); send(sClient, a, 255, 0); } } } closesocket(sClient); } int main(int argc, char* argv[]) { // 初始化WSA WORD sockVersion = MAKEWORD(2, 2); WSADATA wsaData; if (WSAStartup(sockVersion, &wsaData) != 0) { return 0; } // 创建套接字:AF_INET:TCP/IP 协议,数据流,TCP 传输 SOCKET slisten = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (slisten == INVALID_SOCKET) { printf("socket error !"); return 0; } //绑定IP和端口 sockaddr_in sin; sin.sin_family = AF_INET; sin.sin_port = htons(8888); // 端口和客户端端口要相同,否则链接建立不上 sin.sin_addr.S_un.S_addr = htonl(INADDR_ANY); // 这个是any指的是不限制访问IP // char loa[16] = "192.168.15.189"; // 这是指定 IP发送数据 // sin.sin_addr.S_un.S_addr = inet_addr(loa); // 加入指定 IP // 初始化slisten,加载上面代码设置的属性。 if (bind(slisten, (LPSOCKADDR)&sin, sizeof(sin)) == SOCKET_ERROR) // 把sin强制类型转换为sockadd,sin原来是sockaddr_in类型 { printf("bind error !"); } //开始监听 if (listen(slisten, 5) == SOCKET_ERROR) { printf("listen error !"); return 0; } // 以上可以认为是建立服务器联系的固定格式 //这里是多线程服务器,接受多个客户端,可以对比单线程看看多了什么,哪些函数的位置调整了 sockaddr_in remoteAddr; int nAddrlen = sizeof(remoteAddr); while (true) { printf("等待连接...\n"); SOCKET sClient = accept(slisten, (SOCKADDR *)&remoteAddr, &nAddrlen); if (sClient == INVALID_SOCKET) { printf("accept error !"); } else { printf("接受到一个连接:%s \r\n", inet_ntoa(remoteAddr.sin_addr)); if (clientHeadNote == NULL) { clientHeadNote = addClient(); clientEndNote = clientHeadNote; } // 必须要先创建给end节点,然后再创建线程,因为线程的参数通过全局变量传入,而不是通过线程生成函数传入 // 原来线程参数除了 pthread_create()还能通过全局变量传参数 hThread* clientnode = (hThread*)malloc(sizeof(hThread)); // 创建客户端结构体 clientnode->Client = sClient; clientnode->next = NULL; clientHeadNote->next = clientnode; clientEndNote = clientnode; clientnode->Thread = (pthread_t*)malloc(sizeof(pthread_t)); // 创建线程变量 clientnode->index = pthread_create(clientnode->Thread, NULL, ThreadClient, NULL); // 创建线程并执行 } } printf("server is closing\n"); hThread * p; while (clientHeadNote) //释放占用的内存空间 { p = clientHeadNote; clientHeadNote = clientHeadNote->next; delete p; } closesocket(slisten); WSACleanup(); return 0; }这是单线程服务端
#include <stdio.h> #include <winsock2.h> #include <conio.h> #pragma comment(lib,"ws2_32.lib") #pragma waring(disable :4996) int main() { WORD sockVersion = MAKEWORD(2,2); WSADATA wsaData; if(WSAStartup(sockVersion,&wsaData)!=0) { printf("版本与结构体不匹配\n"); return 0; } SOCKET slisten = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); if(slisten==INVALID_SOCKET) { printf("socket error\n"); return 0; } sockaddr_in sin; sin.sin_family = AF_INET; sin.sin_port = htons(8888); sin.sin_addr.S_un.S_addr = htonl(INADDR_ANY); if(bind(slisten,(LPSOCKADDR)&sin,sizeof(sin))==SOCKET_ERROR) { printf("bind error\n"); } if(listen(slisten,5)==SOCKET_ERROR) { printf("listen error\n"); return 0; } sockaddr_in remoteAddr; int nAddrlen=sizeof(remoteAddr); char rev[255]; char sen[244]; strcpy(sen,"okk\n"); printf("等待连接\n"); SOCKET sClient = accept(slisten,(SOCKADDR*)&remoteAddr,&nAddrlen); if(sClient==INVALID_SOCKET) { printf("accpet error\n"); } int ret=0; while(true) { ret=0; ret =recv(sClient,rev,255,0); if(ret>0) { printf("recieve\n"); printf("ret = %d\n",ret); printf("消息为:%s\n",rev); send(sClient,sen,255,0); // 0 代表阻塞发送,缓存起来,按顺序一个一个发 strcpy(rev,""); // 清空旧数据 } Sleep(100); } }这是客户端
#include <winsock2.h> #include <stdio.h> #include <pthread.h> #pragma comment(lib,"ws2_32.lib") #pragma warning(disable : 4996) //格式和服务端一样 int main(int argc, char* argv[]) { WORD sockVersion = MAKEWORD(2, 2); WSADATA data; if (WSAStartup(sockVersion, &data) != 0) { return 0; } SOCKET sclient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (sclient == INVALID_SOCKET) { printf("无效的 socket !"); return 0; } sockaddr_in serAddr; serAddr.sin_family = AF_INET; // 表示使用IPv4地址协议 https://blog.csdn.net/u012736362/article/details/130392547 serAddr.sin_port = htons(8888); char loa[16] = "127.0.0.1"; // 对方IP地址。当服务器的电脑的IP , win建+r 输入cmd,打开命令行,输入再直接 ipconfig/all可查看IP。 serAddr.sin_addr.S_un.S_addr = inet_addr(loa);// IP是读取目标机器的IP,由于一台电脑当服务器和客户端,127.0.0.1是自回路,自己发送给自己 //链接发消息 while(connect(sclient, (sockaddr *)&serAddr, sizeof(serAddr)) == SOCKET_ERROR) { //主动连接服务器 printf("连接错误 !\n"); Sleep(1000); } puts("连接成功!!"); puts("你现在可以向服务器发送信息:"); char sendData[100]; char recData[255]; while (1) { scanf("%s",sendData); send(sclient, sendData, strlen(sendData), 0); // 发送消息 0 代表阻塞 1 代表不阻塞 int ret = recv(sclient, recData, 255, 0); // 接收消息 0 代表不执行这句,下面的都不执行 if (ret > 0) { printf(recData); } } closesocket(sclient); WSACleanup(); return 0; }
TCP/IPC语言实现单个客户端和服务端TCP通信由讯客互联开源代码栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“TCP/IPC语言实现单个客户端和服务端TCP通信”