Программирование на C++ глазами хакера


. Использование сокетов через события Windows - часть 4


Листинг 4.20. Обработка сетевых сообщений в функции WndProc
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int wmId, wmEvent; PAINTSTRUCT ps; HDC hdc;

SOCKET ClientSocket; int ret; char szRecvBuff[1024], szSendBuff[1024];

switch (message) { case WM_USER+1: switch (WSAGETSELECTEVENT(lParam)) { case FD_ACCEPT: ClientSocket = accept(wParam, 0, 0); WSAAsyncSelect(ClientSocket, hWnd, WM_USER+1, FD_READ | FD_WRITE | FD_CLOSE); break;

case FD_READ: ret = recv(wParam, szRecvBuff, 1024, 0); if (ret == 0) break; else if (ret == SOCKET_ERROR) { MessageBox(0, "Recive data filed", "Error", 0); break; } szRecvBuff[ret] = '\0';

strcpy(szSendBuff, "Command get OK");

ret = send(wParam, szSendBuff, sizeof(szSendBuff), 0); break;

case FD_WRITE: //Ready to send data break;

case FD_CLOSE: closesocket(wParam); break; } case WM_COMMAND: ...

Здесь в самом начале добавлен новый оператор case , который проверяет, равно ли пойманное сообщение искомому сетевому сообщению WM_USER+1. Если это сетевое событие, то запускается перебор сетевых событий. Для этого используется оператор switch, который сравнивает указанное в скобках значение с поступающими событиями:

switch (WSAGETSELECTEVENT(lParam))

Как известно, в параметре lParam находятся код ошибки и тип события. Чтобы получить событие, используется функция WSAGETSELECTEVENT. А затем проверяются необходимые нам события. Если произошло соединение со стороны клиента, то выполняется следующий код:

case FD_ACCEPT: ClientSocket = accept(wParam, 0, 0); WSAAsyncSelect(ClientSocket, hWnd, WM_USER+1, FD_READ | FD_WRITE | FD_CLOSE); break;

Сначала принимается соединение с помощью функции accept. Результатом будет сокет, с помощью которого можно работать с клиентом. С этого сокета тоже нужно ловить события, поэтому вызываем функцию WSAAsyncSelect. Чтобы не плодить сообщения, используем в качестве третьего параметра значение WM_USER+1. Это не вызовет конфликтов, потому что серверный сокет обрабатывает только событие FD_ACCEPT, а у клиентского нас интересуют события чтения, записи данных и закрытия сокета.




Начало  Назад  Вперед



Книжный магазин