C++ 异步Winsock服务器';s WndProc未被调用
我正在努力学习如何制作一个合适的Winsock服务器,并通过一些在线示例的尝试和努力获得了以下代码。我的服务器显示在“netstat-an”中,可以通过Hercules IO调试器应用程序连接到。不幸的是,在WndProc中看到的消息框都没有出现 A.h:C++ 异步Winsock服务器';s WndProc未被调用,c++,windows,sockets,winsock,wndproc,C++,Windows,Sockets,Winsock,Wndproc,我正在努力学习如何制作一个合适的Winsock服务器,并通过一些在线示例的尝试和努力获得了以下代码。我的服务器显示在“netstat-an”中,可以通过Hercules IO调试器应用程序连接到。不幸的是,在WndProc中看到的消息框都没有出现 A.h: #include <winsock.h> #pragma comment(lib, "ws2_32.lib") SOCKET s; WSADATA w; #define MY_MESSAGE_NOTIFICATION
#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));
}
#包括
#pragma注释(lib,“ws2_32.lib”)
插座;
WSADATA w;
#定义我的消息通知1048
LRESULT回调WndProc(HWND HWND,UINT消息,WPARAM WPARAM,LPARAM LPARAM)
{
消息框(hwnd,(LPCWSTR)L“Test1”,(LPCWSTR)L“Test1”,MB_OK);
开关(信息)
{
案例我的消息通知:
{
交换机(LPRAM)
{
案件受理:
打破
案例FD_连接:
消息框(hwnd,(LPCWSTR)L“Test2”,(LPCWSTR)L“Test2”,MB_OK);
打破
案例FD_为:
字符缓冲区[80];
memset(buffer,0,sizeof(buffer));
recv(s,buffer,sizeof(buffer)-1,0);
MessageBox(hwnd,(LPCWSTR)缓冲区,(LPCWSTR)L“捕获的文本…”,MB_OK);
打破
案例FD_关闭:
打破
}
}
打破
违约:
返回DefWindowProc(hwnd、message、wParam、lParam);
}
}
int-listenport(int-portno)
{
int error=WSAStartup(0x0202,&w);
如果(错误)
{
返回false;
}
如果(w.wVersion!=0x0202)
{
WSACleanup();
返回false;
}
地址中的SOCKADDR_;
addr.sin_family=AF_INET;
地址sin_端口=htons(端口号);
addr.sin_addr.s_addr=htonl(INADDR_ANY);
s=套接字(AF_INET、SOCK_STREAM、IPPROTO_TCP);
if(s==无效的_套接字)
{
返回false;
}
if(bind(s,(LPSOCKADDR)&addr,sizeof(addr))==SOCKET\u错误)
{
返回false;
}
听(s,索马克斯康);
WSAAsyncSelect(s,GetConsoleWindow(),我的消息通知,(FD_接受| FD_连接|
FD|u READ | FD|u CLOSE);
}
为什么不检查WSAAsyncSelect的返回值,它应该会告诉您出了什么问题,似乎它甚至没有在窗口中注册
通常,您应该避免将console窗口用作HWND(GetConsoleWindow()),因为它是由系统处理的特殊窗口,因此其行为可能不同。
还有什么叫WndProc函数?从外观上看,没有什么,因为您使用的控制台窗口有自己的WndProc
因此,只需尝试为自己创建一个窗口,并在WSAAsyncSelect调用中指定该窗口,使其不可见,这样就不会打扰用户,完成后只需销毁该窗口 您正在告诉
WSAAsyncSelect()
向您不拥有的HWND发送消息。除非您手动对该窗口进行子类化并将WndProc()
连接到该窗口,否则WndProc()
将永远不会收到套接字消息。您需要创建自己的HWND。并确保代码中还有消息循环,否则HWND将永远不会收到消息。尝试将实际窗口句柄传递给WSAAsyncSelect。。传递GetConsoleWindow似乎不正确..我测试了它是否是主cpp中消息框的正确句柄,其中GetConsoleWindow作为hwnd正确绑定它。不过,如果你能告诉我一个更好的函数,我会试试。我不确定是否允许它从窗口过程内部调用MessageBox。也许可以尝试将程序编译为控制台应用程序(控制台应用程序仍然可以创建窗口!),并使用printf
来调试消息?窗口过程未被调用的常见原因是忘记执行消息循环,忘了执行错误检查。代码段中没有消息循环的迹象,有大量缺少错误检查的迹象。永远不要忽略C函数的返回值。我已经作为控制台应用程序进行编译了——没有其他窗口。