server
#include "stdafx.h" #include <string> #include <iostream> #include <WinSock2.h> #include <ws2tcpip.h> #include <process.h> #include <conio.h> #pragma comment(lib,"ws2_32.lib") using namespace std; void unicode2Ansi(const wchar_t *wsBuffer, char *szBuffer, int *nMultyLen = NULL); unsigned int __stdcall listenProc(void *param); unsigned int __stdcall requestProc(void *param); struct SockInfo { SOCKET sock; char addr[64]; int port; }; SOCKET g_sock; SockInfo g_clients[FD_SETSIZE]; int g_totalCnt = 0; bool g_bContinue = true; int _tmain(int argc, _TCHAR* argv[]) { cout << "------------------main thread start------------------" << endl; if (argc < 3) { cout << "invalid parameters!" << endl; cout << "2 parameters are need:" << endl << "param 1: ip;" << endl << "param 2: port." << endl; return 0; } string addr; int port; if (argv[1] != nullptr) { char tmp[256] = "\0"; unicode2Ansi(argv[1], tmp); addr = tmp; } if (argv[2] != nullptr) { char tmp[256] = "\0"; unicode2Ansi(argv[2], tmp); port = atoi(tmp); } cout << "init..." << endl; WSADATA wsaData; int rst = WSAStartup(MAKEWORD(2, 2), &wsaData); if (rst != NO_ERROR) { cout << "WSAStartup failed with:" << rst << endl; return 0; } g_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (g_sock == INVALID_SOCKET) { cout << "create socket failed with:" << WSAGetLastError() << endl; goto goexit; } cout << "init success." << endl << "bind " << addr << ":" << port << "..." << endl; sockaddr_in sockin; sockin.sin_family = AF_INET; sockin.sin_port = htons(port); if (addr.compare("any") == 0) sockin.sin_addr.S_un.S_addr = INADDR_ANY; else inet_pton(AF_INET, addr.c_str(), &sockin.sin_addr); if (bind(g_sock, (SOCKADDR *)&sockin, sizeof(sockin)) == SOCKET_ERROR) { cout << "bind failed with:" << WSAGetLastError() << endl; closesocket(g_sock); goto goexit; } cout << "bind success." << endl << "listen..." << endl; if (listen(g_sock, 10) == SOCKET_ERROR) { cout << "listen failed with:" << WSAGetLastError() << endl; closesocket(g_sock); goto goexit; } unsigned long nblock = 1; if (ioctlsocket(g_sock, FIONBIO, &nblock) == SOCKET_ERROR) { cout << "ioctlsocket failed with:" << WSAGetLastError() << endl; closesocket(g_sock); goto goexit; } HANDLE hThreads[2] = { NULL }; hThreads[0] = (HANDLE)_beginthreadex(NULL, 0, listenProc, NULL, 0, NULL); if (hThreads[0] == NULL) { cout << "start listen thread failed with:" << GetLastError() << endl; closesocket(g_sock); goto goexit; } hThreads[1] = (HANDLE)_beginthreadex(NULL, 0, requestProc, NULL, 0, NULL); if (hThreads[1] == NULL) { cout << "start request thread failed with:" << GetLastError() << endl; closesocket(g_sock); goto goexit; } while (true) { if (_kbhit()) { if (getchar() == 'q') { g_bContinue = false; cout << "recv exit event,now exit!" << endl; for (int i = 0; i < g_totalCnt; i++) closesocket(g_clients[i].sock); closesocket(g_sock); break; } } Sleep(500); } if (WaitForMultipleObjects(2, hThreads, TRUE, INFINITE) == WAIT_OBJECT_0) cout << "all thread had exit" << endl; goexit: WSACleanup(); cout << "------------------main thread exit------------------" << endl; //system("pause"); return 0; } unsigned int __stdcall listenProc(void *param) { cout << "------listen thread start------" << endl; sockaddr_in addr; int addrlen = sizeof(addr); while (g_bContinue) { //cout << "listen..." << endl; SOCKET sock = accept(g_sock, (SOCKADDR *)&addr, &addrlen); if (sock != SOCKET_ERROR) { g_clients[g_totalCnt].sock = sock; inet_ntop(AF_INET, &addr.sin_addr, g_clients[g_totalCnt].addr, 64); g_clients[g_totalCnt].port = ntohs(addr.sin_port); cout << "a new client come:" << g_clients[g_totalCnt].addr << ":" << g_clients[g_totalCnt].port << ",total:" << ++g_totalCnt << endl; } else { int rst = WSAGetLastError(); if (rst == WSAEWOULDBLOCK) continue; cout << "accept failed with:" << rst << endl; break; } Sleep(50); } cout << "------listen thread exit------" << endl; return 0; } unsigned int __stdcall requestProc(void *param) { cout << "------request thread start------" << endl; fd_set readset; timeval tval = { 1, 0 }; while (g_bContinue) { //cout << "waiting request..." << endl; FD_ZERO(&readset); for (int i = 0; i < g_totalCnt; i++) FD_SET(g_clients[i].sock, &readset); int rst = select(0, &readset, NULL, NULL, &tval); if (rst == 0) continue; if (rst > 0) { for (int i = 0; i < g_totalCnt; i++) { if (FD_ISSET(g_clients[i].sock, &readset)) { char buffer[1024] = "\0"; rst = recv(g_clients[i].sock, buffer, 1024, 0); if (rst > 0) { cout << "msg from " << g_clients[i].addr << ":" << g_clients[i].port << ":" << buffer << endl; char msg[256] = "recv your msg!"; send(g_clients[i].sock, msg, 256, 0); continue; } if (rst == 0 || (rst == SOCKET_ERROR &&WSAGetLastError() == WSAECONNRESET)) { closesocket(g_clients[i].sock); cout << g_clients[i].addr << ":" << g_clients[i].port << " quit,total:" << g_totalCnt - 1 << endl; for (int j = i; j < g_totalCnt - 1; j++) g_clients[j] = g_clients[j + 1]; g_totalCnt--; } } } } Sleep(1000); } cout << "------request thread exit------" << endl; return 0; } void unicode2Ansi(const wchar_t *wsBuffer, char *szBuffer, int *nMultyLen) { int len = WideCharToMultiByte(CP_ACP, 0, wsBuffer, -1, NULL, 0, NULL, NULL); char *pbuffer = new char[len + 1]; memset(pbuffer, 0x00, len + 1); if (WideCharToMultiByte(CP_ACP, 0, wsBuffer, -1, pbuffer, len, NULL, NULL) > 0) { memset(szBuffer, 0x00, len + 1); memcpy(szBuffer, pbuffer, len); if (nMultyLen != NULL) *nMultyLen = len; } delete[] pbuffer; }
client:
#include "stdafx.h" #include <WinSock2.h> #include <ws2tcpip.h> #include <iostream> #include <conio.h> using namespace std; #pragma comment(lib,"ws2_32.lib") void unicode2Ansi(const wchar_t *wsBuffer, char *szBuffer, int *nMultyLen = NULL); int _tmain(int argc, _TCHAR* argv[]) { if (argc < 3) { cout << "invalid parameters!" << endl; cout << "2 parameters are need:" << endl << "param 1: server ip;" << endl << "param 2: server port." << endl; return 0; } char szServer[64] = "\0"; int port = 0; if (argv[1] != NULL) unicode2Ansi(argv[1], szServer); if (argv[2] != NULL) { char tmp[64] = "\0"; unicode2Ansi(argv[2], tmp); port = atoi(tmp); } cout << "init..." << endl; WSADATA wsaData; int rst = WSAStartup(MAKEWORD(2, 2), &wsaData); if (rst != NO_ERROR) { cout << "WSAStartup failed with:" << rst << endl; return 0; } SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (sock == INVALID_SOCKET) { cout << "create socket failed with:" << WSAGetLastError() << endl; goto goexit; } cout << "init success." << endl; cout << "connect " << szServer << ":" << port << "..." << endl; sockaddr_in addrin; addrin.sin_family = AF_INET; inet_pton(AF_INET, szServer, &addrin.sin_addr); addrin.sin_port = htons(port); rst = connect(sock, (SOCKADDR *)&addrin, sizeof(addrin)); if (rst == SOCKET_ERROR) { cout << "connect failed with:" << WSAGetLastError() << endl; closesocket(sock); goto goexit; } cout << "connect success." << endl; while (true) { cout << "input message(q for exit):"; char msg[1024] = "\0"; cin.getline(msg, 1024); if (strcmp(msg, "q") == 0) break; rst = send(sock, msg, 1024, 0); if (rst == SOCKET_ERROR) { cout << "send msg failed with:" << WSAGetLastError() << endl; break; } memset(msg, 0x00, sizeof(msg)); rst = recv(sock, msg, 1024, 0); if (rst > 0) { cout << "recv msg:" << msg << endl; continue; } if (rst == 0 || (rst == SOCKET_ERROR &&WSAGetLastError() == WSAECONNRESET)) { cout << "lose connect!" << endl; break; } } closesocket(sock); goexit: WSACleanup(); cout << "exit" << endl; //system("pause"); return 0; } void unicode2Ansi(const wchar_t *wsBuffer, char *szBuffer, int *nMultyLen) { int len = WideCharToMultiByte(CP_ACP, 0, wsBuffer, -1, NULL, 0, NULL, NULL); char *pbuffer = new char[len + 1]; memset(pbuffer, 0x00, len + 1); if (WideCharToMultiByte(CP_ACP, 0, wsBuffer, -1, pbuffer, len, NULL, NULL) > 0) { memset(szBuffer, 0x00, len + 1); memcpy(szBuffer, pbuffer, len); if (nMultyLen != NULL) *nMultyLen = len; } delete[] pbuffer; }
浙公网安备 33010602011771号