スレッドでのTCPソケット送受信(VC++) Windows Sockets APIを使用するTCPソケット送受信のメモです。受信処理は、スレッドの中で行い、マルチスレッドで、通信できるようになります。 tcp_server()は、サーバー側のプログラムです。listen用のソケットを作成して、listenをする、クライアントからの接続要求を受けたら、新しいスレッドを起こして、またlistenを繰り返します。 クライアント側のプログラムは、TCPソケット送受信を参照します。 #include "stdafx.h" #include <winsock2.h> #pragma comment(lib, "ws2_32.lib") DWORD WINAPI tcp_comm_thread(LPVOID lpParam); class CTcpCommThread { public: HANDLE hThread; DWORD ThreadId; SOCKET sockListen; CTcpCommThread() { hThread = NULL; } void Start() { hThread = CreateThread(NULL, 0, tcp_comm_thread, (void *)this, 0, &ThreadId); } ~CTcpCommThread() { if (hThread) { if (WAIT_TIMEOUT == WaitForSingleObject(hThread, 1000 )) { TerminateThread(hThread, 0); } CloseHandle(hThread); hThread = NULL; printf("CloseHandle().\r\n"); } } }; void Release(CTcpCommThread* lpParam) { // 省略↓ // newで作成されたCTcpCommThreadのオブジェクトをdeleteする処理 } DWORD WINAPI tcp_comm_thread(LPVOID lpParam) { SOCKET sockListen = ((CTcpCommThread*)lpParam)->sockListen; SOCKET sockWork; struct sockaddr_in sockAddrInWork; int iSizeofSockAddrInWork = sizeof(sockAddrInWork); sockWork = accept(sockListen, (struct sockaddr *)&sockAddrInWork, &iSizeofSockAddrInWork); if (INVALID_SOCKET == sockWork) { closesocket(sockListen); return -1; } while(1) { char buff[256]; memset(buff, 0, sizeof(buff)); int len = recv(sockWork, buff, 256, 0); if(len <= 0) break; printf("Data Received = %s\n", buff); strcat(buff, "3."); send(sockWork, buff, strlen(buff)+1, 0); } closesocket(sockWork); printf("Eof thread.\n"); Release((CTcpCommThread*)lpParam); ExitThread(0); return 0; } void tcp_server() { unsigned short port = 10000; SOCKET sockListen; struct sockaddr_in sockAddrInListen; memset(&sockAddrInListen, 0, sizeof(sockAddrInListen)); sockAddrInListen.sin_port = htons(port); sockAddrInListen.sin_family = AF_INET; sockAddrInListen.sin_addr.s_addr = htonl(INADDR_ANY); sockListen = socket(AF_INET, SOCK_STREAM, 0); if (INVALID_SOCKET == sockListen) return; if (SOCKET_ERROR == bind(sockListen, (struct sockaddr *) &sockAddrInListen, sizeof(sockAddrInListen))) { closesocket(sockListen); return; } for (int n = 0; n < 100; n ++) { if (SOCKET_ERROR == listen(sockListen, SOMAXCONN)) { closesocket(sockListen); return; } fd_set mask; FD_ZERO(&mask); FD_SET(sockListen, &mask); struct timeval tv={ 1, 0 }; int ret = select((int)sockListen+1, &mask, NULL, NULL, &tv); if (ret == SOCKET_ERROR) { break; } else if (ret == 0) { printf("wait 1 second ...\r\n"); continue; } else if (FD_ISSET(sockListen, &mask)) { CTcpCommThread* ptcthread = new CTcpCommThread(); ptcthread->sockListen = sockListen; ptcthread->Start(); } } closesocket(sockListen); } int main(int argc, char* argv[]) { WSADATA wsadata; if (0 != WSAStartup(MAKEWORD(2,0), &wsadata)) { printf("WSAStartup Faild.\n"); return -1; } tcp_server(); WSACleanup(); return 0; } |