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;
}