慕无忌1623718
#include <winsock.h>#include <stdio.h>#define PORT 5150 //端口#define MSGSIZE 1024 //信息大小#pragma comment(lib, "ws2_32.lib")int g_iTotalConn = 0; //连接数量SOCKET g_CliSocketArr[FD_SETSIZE]; //套接字数组DWORD WINAPI WorkerThread(LPVOID lpParameter);//线程函数int main(){ WSADATA wsaData; SOCKET sListen, sClient; SOCKADDR_IN local, client; int iaddrSize = sizeof(SOCKADDR_IN); DWORD dwThreadId; // Initialize Windows socket library //装载套接字库 WSAStartup(0x0202, &wsaData); // Create listening socket //创建套接字 sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); // Bind //绑定 local.sin_addr.S_un.S_addr = htonl(INADDR_ANY); local.sin_family = AF_INET; local.sin_port = htons(PORT); bind(sListen, (struct sockaddr *)&local, sizeof(SOCKADDR_IN)); // Listen //监听 listen(sListen, 3); // Create worker thread //创建线程 CreateThread(NULL, 0, WorkerThread, NULL, 0, &dwThreadId); while (TRUE) { // Accept a connection //接受一个连接,返回的是客户套的套接字 sClient = accept(sListen, (struct sockaddr *)&client, &iaddrSize); //这里client的SOCKADDR_IN client 中可以取出IP printf("Accepted client:%s:%d\n", inet_ntoa(client.sin_addr), ntohs(client.sin_port)); // Add socket to g_CliSocketArr //把客户端套接字放入数组中 g_CliSocketArr[g_iTotalConn++] = sClient; } return 0;}DWORD WINAPI WorkerThread(LPVOID lpParam)//线程{ int i; fd_set fdread;//结构 int ret; struct timeval tv = {1, 0};//超时时间 SELECT模型中用到的这里是1秒 char szMessage[MSGSIZE];//信息数组,事实上就是个缓冲区 while (TRUE) { FD_ZERO(&fdread);//清空fd_set结构 for (i = 0; i < g_iTotalConn; i++) { FD_SET(g_CliSocketArr[i], &fdread);//把客户套接字放到SELECT要求的数组中 } //************************************** // We only care read event //只关心读的情况 ret = select(0, &fdread, NULL, NULL, &tv); if (ret == 0) { // Time expired 超时 continue; } //如果SELECT返回不是0 for (i = 0; i < g_iTotalConn; i++) { if (FD_ISSET(g_CliSocketArr[i], &fdread)) { // A read event happened on g_CliSocketArr[i] //一个可读发生在这个套接字上 ret = recv(g_CliSocketArr[i], szMessage, MSGSIZE, 0); //把它读出到缓冲区 if (ret == 0 || (ret == SOCKET_ERROR && WSAGetLastError() == WSAECONNRESET)) { // Client socket closed //客户端关闭 printf("Client socket %d closed.\n", g_CliSocketArr[i]); closesocket(g_CliSocketArr[i]);//关闭这个套接字 if (i < g_iTotalConn - 1) { //将数组中最后一个套接字挪到当前的位置上 g_CliSocketArr[i--] = g_CliSocketArr[--g_iTotalConn]; } } else { // We received a message from client //如果以上没发生,那么就接收到一个客户端的信息 szMessage[ret] = '\0'; //直接回送回去 send(g_CliSocketArr[i], szMessage, strlen(szMessage), 0); } } } } return 0;}1