Tim*_*Tim 5 c++ sockets mfc casyncsocket
我被要求为朋友查看一些代码.(由于MFC和许多糟糕的代码,我正确地犹豫了,但他赢了......)
这是一个基于对话框的应用程序,它使用了一个CAsyncSocket.
问题表现在一些不间断的debugbreaks和其他类似的事情 - MFC ENSURE()宏也有问题- 检查套接字是否为null.所有问题都发生在MFC的深处.
如果使用Vista/XP中的主题,一些谷歌搜索显示可能的资源泄漏,但我不认为这是问题.
基于我几个小时的调试,代码非常差,但基本上它正在执行以下操作:
(建立连接时没有问题 - 只有在没有连接时才会出现这种情况)
CAsyncSocket对象上)OnConnect()我们被通知连接不起作用/没有连接.OnConnect()不好)那么我们打电话CAsyncSocket::Close(),然后打电话CAsyncSocket::Create()(没有参数)然后打电话CAsyncSocket::Connect(server, port) 请注意,初始调用Connect()没有先前的调用Create().
Create()需要?(如果我删除它然后它不再崩溃,但我重新建立连接时也不连接)我固定的代码,这样,所有的路径经过呼吁Create()然后Connect().
我仍然遇到断言问题CAsyncSocket::DoCallBack()- 下面代码的最后一行是断言:
void PASCAL CAsyncSocket::DoCallBack(WPARAM wParam, LPARAM lParam)
{
if (wParam == 0 && lParam == 0)
return;
// Has the socket be closed - lookup in dead handle list
CAsyncSocket* pSocket = CAsyncSocket::LookupHandle((SOCKET)wParam, TRUE);
// If yes ignore message
if (pSocket != NULL)
return;
pSocket = CAsyncSocket::LookupHandle((SOCKET)wParam, FALSE);
if (pSocket == NULL)
{
// Must be in the middle of an Accept call
pSocket = CAsyncSocket::LookupHandle(INVALID_SOCKET, FALSE);
ENSURE(pSocket != NULL);
Run Code Online (Sandbox Code Playgroud)
如果我单步执行,那么我会收到消息框:"遇到不正确的参数"
我想(但我不确定)MFC在我关闭它之后试图回拨套接字.它是在一个回调方法(DoCallback())但我已经调用Close()了套接字.
所以它确实看起来像一个MFC问题,除非我应该首先取消订阅.
你的选择真的.如果你认为你有更多的运气与另一个套接字实现,那么这样做.
但是,微软有很多开发人员(我相信其中一些甚至可能是好的开发人员).您可能,只是可能,要考虑该故障不会全部铺设在其末端的可能性.
在我看来,您可以获得的API和产品的帮助量也很大.
也许如果您花时间了解MFC模型,您将获得"AHA"时刻并更好地理解它.我不是Winsock的粉丝 - 我更习惯于UNIX世界,其中同步是要走的路,如果你想要async-type behavor,你只需运行单独的进程/线程.
我怀疑,CAsyncSocket仍然受到MFC是一个单线程模型(就GUI而言)这一事实的困扰,尽管Windows已经有一段时间真正的先发制人线程.[我可能错误的是这个hamstrung评论,因为我直接使用Win32已经有一段时间了].
更新:
根据您说明您正在做什么的更新,我非常确定您在创建之前不允许连接.引用http://msdn.microsoft.com/en-us/library/3d46645f(VS.80).aspx ,
要使用CAsyncSocket对象,请调用其构造函数,然后调用Create函数以创建基础套接字句柄...并为客户端套接字调用Connect成员函数.
至于为什么,我认为这是一个额外的复杂性,因为Windows需要在事件泵浦环境中执行异步套接字,因为它们无法阻止主GUI线程.
在UNIXy环境中,没有事件线程(正常进程)或网络操作只是手动(在GUI应用程序中)到另一个线程.
这很可能是很久以前在WinSock中做出的一个设计决策(可能是在Windows 3.11中,这是一个限制性更强的环境,可以进行异步操作)并继续进行[虽然这是我的猜想,UNIX套接字API从来没有这个一种异步行为,其中消息被抽取,它总是倾向于使用select()或线程/进程].
进一步更新:
如果您在套接字对象上有挂起操作时关闭和/或删除了套接字对象,则通常会发生该断言(非异常).在你的情况下,我建议你关闭时仍然尝试连接.
然后,当连接成功或失败时,将调用回调,并且无法在表中找到您的套接字.
这不是MFC问题,是你朋友的代码违反了合同.如果进行连接(或任何异步操作),则必须在关闭套接字之前等待成功或失败(或继续进行操作) - 在这种情况下,这意味着等待对OnConnect()函数的调用.
从内存中,您可以create()在创建异步套接字时调用,然后发生其他所有操作以响应到达消息队列的消息(即调用您的OnXXX()函数).像所有Win32 GUI一样,消息应该驱动程序(代码运行以响应消息).这段代码看起来越来越像经典编码,其中程序驱动一切 - 这种方式是疯狂的,因为你将拥有你的程序和异步套接字'线程'争夺控制权.
我有一段时间没有看过它,但是你应该能够得到一个CHATSRVR示例程序,它将告诉你如何做到这一点.
| 归档时间: |
|
| 查看次数: |
4203 次 |
| 最近记录: |