Windowsネットワークプログラミング(五):マルチスレッドメッセージ処理

45246 ワード

サービス側では、accept()関数を呼び出してクライアント接続の要求に同意した後、このクライアントとの通信を処理した後、accept()に戻って次のクライアントの接続を待つ必要があります.1つのクライアントが接続を要求したとき、サービス側がaccept()で待っていなければ、クライアントはサービス側に正常に接続できません.したがって、同時クライアント接続のサービス側は必ずマルチスレッドです.
サービス:
#include 

#include 

#include 

#include 

#pragma comment(lib,"ws2_32.lib")



DWORD WINAPI CommunicationThread(LPVOID lpParameter)

{

	SOCKET socket = (SOCKET)lpParameter;

	DWORD dwTid = GetCurrentThreadId();

	int bytesSent;

	LPSTR szRequest = (LPSTR)HeapAlloc(GetProcessHeap(), 0, 1024);

	int iResult = recv(socket, szRequest, 1024, 0);

	if (iResult == 0) //  , 

	{

		printf("Connection closing...
"
); HeapFree(GetProcessHeap(), 0, szRequest); closesocket(socket); return 1; } else if (iResult == SOCKET_ERROR) // ,socket { printf("recv failed:%d
"
, WSAGetLastError()); HeapFree(GetProcessHeap(), 0, szRequest); closesocket(socket); return 1; } else if (iResult > 0) // { printf("\t CommunicationThread(%d)\t Bytes received:%d
"
, dwTid, iResult); printf("\t CommunicationThread(%d)\t request string is (%s)
"
, dwTid, szRequest); if (lstrcmpi(szRequest, "download file") == 0) { HANDLE hFile; LPVOID lpReadBuf; DWORD dwBytesRead; DWORD dwSendFile = 0; DWORD dwFileSize; hFile = CreateFile("download.txt", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { printf("\tCommunicationThread\tCould not open file (error %d)
"
, GetLastError()); send(socket, "error", 6, 0); closesocket(socket); return 1; } dwFileSize = GetFileSize(hFile, NULL); lpReadBuf = HeapAlloc(GetProcessHeap(), 0, 4096); while (true) { if (!ReadFile(hFile, lpReadBuf, 4096, &dwBytesRead, NULL)) { printf("\t CommunicationThread\tCould not read from file (error %d)
"
, GetLastError()); closesocket(socket); CloseHandle(hFile); return 1; } bytesSent = send(socket, (const char *)lpReadBuf, dwBytesRead, 0); if (bytesSent == SOCKET_ERROR) { printf("\tCommunicationThread\tsend error %d
"
, WSAGetLastError()); closesocket(socket); CloseHandle(hFile); return 1; } printf("\tCommunicationThread(%d)\tsend %d bytes
"
, dwTid, bytesSent); dwSendFile += dwBytesRead; if (dwSendFile == dwFileSize) { printf("\tCommunicationThread\tFile download ok
"
); break; } } HeapFree(GetProcessHeap(), 0, lpReadBuf); CloseHandle(hFile); closesocket(socket); } else if (lstrcmpi(szRequest, "get information") == 0) { bytesSent = send(socket, "this is information", sizeof("this is information") + 1, 0); if (bytesSent == SOCKET_ERROR) { printf("\tCommunicationThread\t send error:%d
"
, WSAGetLastError()); closesocket(socket); return 1; } printf("\tCommunicationThread(%d)\tsend %d bytes
"
, dwTid, bytesSent); } else { printf("unreferenced request
"
); } } HeapFree(GetProcessHeap(), 0, szRequest); closesocket(socket); return 0; } int _tmain(int argc, _TCHAR argv[]) { WSADATA wsaData; SOCKET ListenSocket = INVALID_SOCKET; SOCKET ClientSocket = INVALID_SOCKET; ADDRINFO hints; ADDRINFO *result = NULL; ZeroMemory(&hints, sizeof(hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; hints.ai_flags = AI_PASSIVE; int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); if (iResult != NO_ERROR) { printf("WSAStartup failed with error:%d
"
, iResult); return 1; } iResult = getaddrinfo(NULL, "12000", &hints, &result); if (iResult != NO_ERROR) { printf("getaddrinfo failed with error:%d
"
, iResult); WSACleanup(); return 1; } ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol); if (ListenSocket == INVALID_SOCKET) { printf("socket failed with error:%d", WSAGetLastError()); freeaddrinfo(result); WSACleanup(); return 1; } iResult = bind(ListenSocket, result->ai_addr, result->ai_addrlen); if (iResult == SOCKET_ERROR) { printf("bind failed with error:%d", WSAGetLastError()); freeaddrinfo(result); closesocket(ListenSocket); WSACleanup(); return 1; } freeaddrinfo(result); iResult = listen(ListenSocket, SOMAXCONN); if (iResult == SOCKET_ERROR) { printf("listen failed with error:%d", WSAGetLastError()); closesocket(ListenSocket); WSACleanup(); return 1; } while (true) { ClientSocket = accept(ListenSocket, NULL, NULL); if (ClientSocket == INVALID_SOCKET) { printf("accept failed with error:%d", WSAGetLastError()); closesocket(ListenSocket); break; } if (!CreateThread(NULL, 0, CommunicationThread, (LPVOID)ClientSocket, 0, NULL)) { printf("CreateThread error %d", GetLastError()); break; } } WSACleanup(); return 0; }

クライアント:
#include 

#include 

#pragma comment(lib,"ws2_32.lib")

int _tmain(int argc, _TCHAR* argv[])

{

	WSADATA wsaData;//  

	SOCKET ConnectSocket;// socket

	SOCKADDR_IN clientService;//  

	int bytesSent;

	int bytesRecv = 0;

	LPVOID recvbuf;//  

	char sendbuf[32] = "get information";//  

	clientService.sin_family = AF_INET;

	clientService.sin_addr.s_addr = inet_addr("127.0.0.1");

	clientService.sin_port = htons(12000);



	int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);

	if (iResult != NO_ERROR)

	{

		printf("Error at WSAStartup()
"
); return 1; } ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (ConnectSocket == INVALID_SOCKET) { printf("Error at socket(): %ld
"
, WSAGetLastError()); WSACleanup(); return 1; } if (connect(ConnectSocket, (SOCKADDR*)&clientService, sizeof(clientService)) == SOCKET_ERROR) { printf("Failed to connect(%d)
"
, WSAGetLastError()); WSACleanup(); return 1; } if (argc == 2 & (!lstrcmp(argv[1], "-d"))) { lstrcpyn(sendbuf, "download file", 32); } // bytesSent = send(ConnectSocket, // socket sendbuf,// lstrlen(sendbuf) + 1,// 0);// if (bytesSent == SOCKET_ERROR) { printf("send error (%d)
"
, WSAGetLastError()); closesocket(ConnectSocket); return 1; } recvbuf = HeapAlloc(GetProcessHeap(), 0, 8192); while (bytesRecv != SOCKET_ERROR) { //Sleep(50); bytesRecv = recv(ConnectSocket, // socket (char*)recvbuf, // 8192,// 0);// if (bytesRecv == 0) { printf("Connection Closed.
"
); break; } // TODO, , printf("Bytes Recv: %ld
"
, bytesRecv); } HeapFree(GetProcessHeap(), 0, recvbuf); WSACleanup(); return 0; }