Я пытаюсь научиться создавать правильный сервер Winsock и получить код ниже от проб и усилий с примерами, найденными в Интернете. Мой сервер появляется в "netstat -an" и может быть подключен через приложение отладчика Hercules IO. К сожалению, ни один из ящиков сообщений, замеченных в WndProc, не появляется.
Sockets.h:
#include <winsock.h>
#pragma comment(lib, "ws2_32.lib")
SOCKET s;
WSADATA w;
#define MY_MESSAGE_NOTIFICATION 1048
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
MessageBox(hwnd, (LPCWSTR)L"Test1", (LPCWSTR)L"Test1", MB_OK);
switch (message)
{
case MY_MESSAGE_NOTIFICATION:
{
switch (lParam)
{
case FD_ACCEPT:
break;
case FD_CONNECT:
MessageBox(hwnd,(LPCWSTR)L"Test2",(LPCWSTR)L"Test2",MB_OK);
break;
case FD_READ:
char buffer[80];
memset(buffer, 0, sizeof(buffer));
recv (s, buffer, sizeof(buffer)-1, 0);
MessageBox(hwnd, (LPCWSTR)buffer, (LPCWSTR)L"Captured Text…", MB_OK);
break;
case FD_CLOSE:
break;
}
}
break;
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
}
int ListenOnPort(int portno)
{
int error = WSAStartup (0x0202, &w);
if (error)
{
return false;
}
if (w.wVersion != 0x0202)
{
WSACleanup ();
return false;
}
SOCKADDR_IN addr;
addr.sin_family = AF_INET;
addr.sin_port = htons (portno);
addr.sin_addr.s_addr = htonl (INADDR_ANY);
s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (s == INVALID_SOCKET)
{
return false;
}
if (bind(s, (LPSOCKADDR)&addr, sizeof(addr)) == SOCKET_ERROR)
{
return false;
}
listen(s, SOMAXCONN);
WSAAsyncSelect (s, GetConsoleWindow(), MY_MESSAGE_NOTIFICATION, (FD_ACCEPT | FD_CONNECT |
FD_READ | FD_CLOSE));
}
Вы сообщаете WSAAsyncSelect()
чтобы отправлять сообщения HWND, которые у вас нет. Если вы не вручную подклассифицировали это окно и подключили WndProc()
к нему, WndProc()
никогда не получит сообщения сокета. Вместо этого вам нужно создать свой собственный HWND. И убедитесь, что у вас также есть цикл сообщений в вашем коде, или ваш HWND никогда не получит сообщений.
Почему бы вам просто не проверить возвращаемое значение WSAAsyncSelect, он должен сказать вам, что не так, кажется, что он даже не регистрируется в окне.
Как правило, вам следует избегать использования окна консоли в качестве HWND (GetConsoleWindow()), поскольку это специальное окно, обрабатываемое системой, и поэтому оно может вести себя по-разному. Также, что вызывает функцию WndProc? по внешнему виду ничего нет, поскольку вы используете консольное окно с собственным WndProc!
Поэтому просто попробуйте сделать окно для себя и укажите, что в вызове WSAAsyncSelect и сделать его невидимым, чтобы он вообще не беспокоил пользователя, и когда вы закончили просто уничтожить окно!