Created
          April 29, 2020 04:16 
        
      - 
      
 - 
        
Save SangSama/07b0d2c7a5f35b9c5dd54b991e4406b3 to your computer and use it in GitHub Desktop.  
Revisions
- 
        
SangSama created this gist
Apr 29, 2020 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,190 @@ #include <stdio.h> #define _WINSOCK_DEPRECATED_NO_WARNINGS #include <winsock2.h> #pragma warning(disable:4996) #pragma comment(lib, "ws2_32") #define WM_SOCKET WM_USER + 1 BOOL CALLBACK WinProc(HWND, UINT, WPARAM, LPARAM); void RemoveClient(CLIENT_INFO*, int*, int*); typedef struct { SOCKET client; BOOL isRegistered; char* id; } CLIENT_INFO; CLIENT_INFO clients[64]; int numClients = 0; int main() { WSADATA wsa; WSAStartup(MAKEWORD(2, 2), &wsa); SOCKADDR_IN addr; addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(INADDR_ANY); addr.sin_port = htons(9000); SOCKET listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); bind(listener, (SOCKADDR*)&addr, sizeof(addr)); listen(listener, 5); WNDCLASS wndclass; const CHAR* providerClass = "AsyncSelect"; HWND window; wndclass.style = 0; wndclass.lpfnWndProc = (WNDPROC)WinProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = NULL; wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = (LPCWSTR)providerClass; if (RegisterClass(&wndclass) == 0) return NULL; // Create a window if ((window = CreateWindow((LPCWSTR)providerClass, L"", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, NULL, NULL)) == NULL) return NULL; WSAAsyncSelect(listener, window, WM_SOCKET, FD_ACCEPT); MSG msg; // truyen nhan du lieu while (GetMessage(&msg, NULL, 0, 0) > 0) { TranslateMessage(&msg); DispatchMessage(&msg); } } BOOL CALLBACK WinProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam) { int index; if (wMsg == WM_SOCKET) { // kiem tra loi if (WSAGETSELECTERROR(lParam)) { closesocket(wParam); return TRUE; } // chap nhan ket noi if (WSAGETSELECTEVENT(lParam) == FD_ACCEPT) { SOCKET client = accept(wParam, NULL, NULL); printf("New client accepted: %d\n", client); CLIENT_INFO clientInfo; clientInfo.client = client; clientInfo.isRegistered = FALSE; clientInfo.id = NULL; clients[numClients] = clientInfo; numClients++; const char* helloMsg = "Dang nhap theo cu phap \"[client_id:] [your_id]\".\n"; send(client, helloMsg, strlen(helloMsg), 0); WSAAsyncSelect(client, hWnd, WM_SOCKET, FD_READ | FD_CLOSE); // them 2 mat na READ, CLOSE // (soket client, cua so , ma thong diep, su kien) => CALLBACk lai duoc goi } // client dk giai phong ben tren nen se luwu vao wParam if (WSAGETSELECTEVENT(lParam) == FD_READ) { char buf[256]; const char* errorMsg = "Sai cu phap. Hay nhap lai.\n"; int ret; ret = recv(wParam, buf, sizeof(buf), 0); for (int i = 0; i < numClients; i++) { if (clients[i].client == wParam) { index = i; break; } } char cmd[16], id[32], tmp[32]; buf[ret] = 0; printf("Received: %s\n", buf); if (!clients[index].isRegistered) { ret = sscanf(buf, "%s %s %s", cmd, id, tmp); // kiem tra cu phap if (ret == 2) { if (strcmp(cmd, "client_id:") == 0) { const char* okMsg = "Dang nhap thanh cong. Hay nhap thong diep de chuyen tiep.\n"; send(wParam, okMsg, strlen(okMsg), 0); clients[index].id = id; clients[index].isRegistered = TRUE; } else { send(wParam, errorMsg, strlen(errorMsg), 0); } }else{ send(wParam, errorMsg, strlen(errorMsg), 0); } } else { char sendBuf[256]; ret = sscanf(buf, "%s", cmd); if (ret == -1 || cmd[0] != '@'){ send(wParam, errorMsg, strlen(errorMsg), 0); } else { char* id = clients[index].id; sprintf(sendBuf, "%s: %s", id, buf + strlen(cmd) + 1); if (strcmp(cmd, "@all") == 0) { // Chuyen tiep tin nhan den cac client khac for (int i = 0; i < numClients; i++) if (clients[i].client != wParam) send(clients[i].client, sendBuf, strlen(sendBuf), 0); } else { for (int i = 0; i < numClients; i++) if (strcmp(clients[i].id, cmd + 1) == 0) send(clients[i].client, sendBuf, strlen(sendBuf), 0); } } } } if (WSAGETSELECTEVENT(lParam) == FD_CLOSE) { RemoveClient(clients, &numClients, &index); closesocket(wParam); } } } void RemoveClient(CLIENT_INFO* clients, int* numClients, int* i) { if (*i < *numClients - 1) clients[*i] = clients[*numClients - 1]; free(clients[*i].id); *numClients = *numClients - 1; *i = *i - 1; }