我被要求为朋友查看一些代码。(由于 MFC 和很多糟糕的代码,我犹豫了一下,但他赢了……)
这是一个基于对话框的应用程序,它使用CAsyncSocket
.
问题体现在一些不间断的调试中断和其他类似的事情上——MFC 宏也存在问题ENSURE()
——检查套接字是否为空。所有的问题都发生在 MFC 的深处。
如果在 Vista/XP 中使用主题,一些谷歌搜索显示可能存在资源泄漏,但我认为这不是问题所在。
根据我几个小时的调试,代码非常糟糕,但基本上它正在执行以下操作:
(建立连接时没有问题 - 只有没有连接时才会出现这种情况)
- 调用 Connect(server, socket) (在派生
CAsyncSocket
对象上) - 在
OnConnect()
我们被通知连接不起作用/未连接。 - 在主对话框/应用程序的窗口计时器内有一个计时器。当定时器事件/处理程序被调用时,我们检查是否连接。
- 如果我们检测到我们没有连接(
OnConnect()
不好)然后我们调用CAsyncSocket::Close()
,然后调用CAsyncSocket::Create()
(没有参数)然后调用CAsyncSocket::Connect(server, port)
请注意,初始调用Connect()
之前没有调用Create()
.
我的第一个真正的问题:
- 两者有什么区别,为什么
Create()
需要?(如果我删除它,那么它不再崩溃,但是当我重新建立连接时我也没有连接)
一般问题:
- 上面的代码设计到底有什么问题?
- 一般来说,这应该如何工作?
编辑:
我修复了代码,以便所有路径都通过调用Create()
then 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);
如果我逐步完成,那么我会收到消息框:“遇到不正确的论点”
我认为(但不确定)MFC 在我关闭它之后试图回调套接字。它在一个回调方法(DoCallback()
)中,但我已经调用Close()
了套接字。
所以它看起来确实像一个 MFC 问题,除非我应该先取消订阅。