偶尔玩的时候,碰上 CSocket 这个类,碰上 SendTo 这个成员函数,它用无连接方式(即UDP啦)发送数据,就是不管目标地址存不存在,你要发送50字节它就返回50,告诉你发送了50字节;这是我测试过的,我乱填个地址,它返回值也一样是你原来要它发送的字节数;
CSocket 从 CAsyncSocket(导步Socket) 派生,就是这个CAsyncSocket,太深奥了(对我来说),且听我慢慢道来;
首先派生一个类,很简单:
class CMessSocket : public CSocket
{
public:
virtual void OnReceive(int nErrorCode);
};
void CMessSocket::OnReceive(int nErrorCode)
{
MessageBox(NULL, "OnRceive被执行", "注意", MB_OK);
return;
}
就这么多, 然后, 在程序初始化时,同时初始化Socket:
CMessSocket m_socket;
AfxSocketInit(NULL);
m_socket.Create(4321,SOCK_DGRAM);
也很简单,MFC看上去就是十分简单....
要发送数据? 更简单:
m_socket.SendTo(szSend, 50, 137, "192.168.0.101", 0);
其中 szSend 是存放数据的地方,50个字节, 目标端口是137,地址是192.168.0.101, 最后那个标志参数留0;
====> 其实我想说的都不是这些,感兴趣的都不是这些,而是:
当 SendTo 执行完毕, 它肯定是返回 50,告诉你已经发送了 50 字节,无论地址是否真的存在,那么这样意义何在呢?如果事先已经确定地址存在了又不同;但是, CAsyncSocket 会帮你做这些事,如果目标存在,并成功发送,会调用 OnReceive 函数, 如果目标不存在或发送不成功,它绝不会调用 OnReceive 函数。
我很想知道 CAsyncSocket 是如何判断的,但是从 SendTo 的执行过程里我找不到一丁点的蛛丝马迹,这个 SendTo 最终还是一路地跑去执行 WinSock 的 SendTo;
我正在奇怪 CAsyncSocket 是如何判断的,我又遇到了一个更加黑暗的问题: (看如下代码)
char szBuffer[260];
m_socket.SendTo(szSend, 50, 137, "192.168.0.101", 0);
memset(szBuffer, 0, 260);
wsprintf(szBuffer, "Microsoft");
HWND hWin = ::FindWindow(NULL, "test");
if(hWin == NULL)
lstrcpy(szBuffer, "无聊的测试");
else
{
int i = 58;
wsprintf(szBuffer, "%d", i);
}
::MessageBoxA(NULL, szBuffer, "啦啦啦", MB_OK);
__asm
{
push eax;
pop eax;
}
return;
=====> 我刚才说过了,如果目标地址存在并且发送成功,会跳到 OnReceive 里去执行; 现在, 你猜一猜, 上面这段代码, 执行到哪里才会跳到 OnReceive 里去 ????
执行 SendTo 时跳到 OnReceive 里去吗? 错;
SendTo 执行完毕后跳到 OnReceive 里去吗? 错;
执行 SendTo 的下一句的跳到 OnReceive 里去吗? 都不是...
上面这段代码,只有执行 ::MessageBoxA(NULL, szBuffer, "啦啦啦", MB_OK); 这句, 才会跳到 OnReceive 里去!!!
我都傻了... 我太菜了;
当最初的 m_socket.Create(4321,SOCK_DGRAM); 执行时, 这个CAsyncSocket会创建一个线程, 这个线程是高优先级的,问题就出在这个线程上面;但是我调试的时候,一直没有看到这个线程有什么动作,也许是我太菜了;
我真正领教了一下什么叫做MFC,什么叫做异步, 太猛了(对我来说 ^_^);
[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法