我正在努力学习制作一个合适的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));
}
答案 0 :(得分:1)
您告诉WSAAsyncSelect()
向您不拥有的HWND发送消息。除非您手动将该窗口子类化并将WndProc()
连接到它,否则WndProc()
将永远不会收到套接字消息。您需要创建自己的HWND。并确保您的代码中也有消息循环,否则您的HWND将永远不会收到消息。
答案 1 :(得分:0)
为什么不直接检查WSAAsyncSelect的返回值,它应该告诉你什么是错的,它似乎甚至没有在窗口上注册。
通常,您应该避免将控制台窗口用作HWND(GetConsoleWindow()),因为它是由系统处理的特殊窗口,因此它可能表现不同。 是什么叫WndProc功能呢?因为你使用控制台的窗口,它的外观没什么,有自己的 WndProc!
因此,只需尝试为自己创建一个窗口并在WSAAsyncSelect调用中指定它并使其不可见,这样它就不会打扰用户,当你完成时只需破坏窗口!