1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
| #include <winsock2.h> #include <ws2tcpip.h> #include <stdio.h> #include <stdlib.h> #include <windows.h> #include <string.h> #pragma comment(lib,"WS2_32.lib") #define MAX_CLNT 256 #define BUF_SIZE 100
void error_handling(const char* msg); DWORD WINAPI ThreadProc(LPVOID lpParam); void send_msg(char* msg, int len); HANDLE g_hEvent; int clnt_cnt = 0; int clnt_socks[MAX_CLNT]; HANDLE hThread[MAX_CLNT];
int main() { WSADATA wsaData; WORD sockVersion = MAKEWORD(2, 2); WSAStartup(sockVersion, &wsaData);
g_hEvent = CreateEvent(NULL, FALSE, TRUE, NULL);
SOCKET serv_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (serv_sock == INVALID_SOCKET) error_handling("Failed socket()");
struct sockaddr_in sin; sin.sin_family = AF_INET; sin.sin_port = htons(8888); sin.sin_addr.s_addr = INADDR_ANY;
if (bind(serv_sock, (SOCKADDR*)&sin, sizeof(sin)) == SOCKET_ERROR) error_handling("Failed bind()");
if (listen(serv_sock, 256) == SOCKET_ERROR) error_handling("Failed listen()"); printf("Start listen:\n");
struct sockaddr_in remoteAddr; int nAddrLen = sizeof(remoteAddr); DWORD dwThreadId; SOCKET clnt_sock;
while (TRUE) { printf("等待新连接\n"); clnt_sock = accept(serv_sock, (SOCKADDR*)&remoteAddr, &nAddrLen); if (clnt_sock == INVALID_SOCKET) { printf("Failed accept()"); continue; }
WaitForSingleObject(g_hEvent, INFINITE); hThread[clnt_cnt] = CreateThread( NULL, NULL, ThreadProc, (void*)&clnt_sock, 0, &dwThreadId); clnt_socks[clnt_cnt++] = clnt_sock; SetEvent(g_hEvent);
char ip_str[INET_ADDRSTRLEN]; inet_ntop(AF_INET, &remoteAddr.sin_addr, ip_str, sizeof(ip_str)); printf(" 接受到一个连接:%s 执行线程ID:%d\r\n", ip_str, dwThreadId); } WaitForMultipleObjects(clnt_cnt, hThread, TRUE, INFINITE); for (int i = 0; i < clnt_cnt; i++) { CloseHandle(hThread[i]); } closesocket(serv_sock); WSACleanup(); return 0; }
void error_handling(const char* msg) { printf("%s\n", msg); WSACleanup(); exit(1); }
DWORD WINAPI ThreadProc(LPVOID lpParam) { int clnt_sock = *((int*)lpParam); int str_len = 0, i; char msg[BUF_SIZE];
while ((str_len = recv(clnt_sock, msg, sizeof(msg), 0)) != -1) { send_msg(msg, str_len); printf("群发送成功\n"); } printf("客户端退出:%d\n", GetCurrentThreadId());
WaitForSingleObject(g_hEvent, INFINITE); for (i = 0; i < clnt_cnt; i++) { if (clnt_sock == clnt_socks[i]) { while (i++ < clnt_cnt - 1) clnt_socks[i] = clnt_socks[i + 1]; break; } } clnt_cnt--; SetEvent(g_hEvent); closesocket(clnt_sock); return NULL; }
void send_msg(char* msg, int len) { int i; WaitForSingleObject(g_hEvent, INFINITE); for (i = 0; i < clnt_cnt; i++) send(clnt_socks[i], msg, len, 0); SetEvent(g_hEvent); }
|