- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我被要求为 friend 查看一些代码。 (由于 MFC 和很多糟糕的代码,我犹豫是对的,但他赢了……)
这是一个基于对话框的应用程序,使用了 CAsyncSocket
。
问题表现为一些不间断的调试中断和其他类似的事情——MFC ENSURE()
宏也有问题——检查套接字是否为空。所有问题都发生在 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);
如果我逐步执行该操作,则会收到消息框:“遇到不正确的参数”
我认为(但不确定)MFC 正试图在我关闭套接字后回调它。它在回调方法 (DoCallback()
) 中,但我已经在套接字上调用了 Close()
。
所以它看起来确实像 MFC 问题,除非我应该先取消订阅。
最佳答案
真的是你的选择。如果您认为使用另一个套接字实现会更幸运,那就去做吧。
但是,Microsoft 有很多开发人员(我相信其中一些甚至可能是优秀的)。您可能,只是可能,想考虑这样一种可能性,即错误并不全都出在他们的头上。
在我看来,您可以获得的有关他们的 API 和产品的大量帮助也不错。
也许如果您花时间了解 MFC 模型,您会得到那个“顿悟”时刻并更好地理解它。我不是 Winsock 的粉丝 - 我更习惯于 UNIX 世界,其中同步是要走的路,如果你想要异步类型的行为,你只需运行单独的进程/线程。
我怀疑 CAsyncSocket 仍然受到 MFC 是单线程模型(就 GUI 而言)这一事实的阻碍,即使 Windows 已经拥有真正的抢占式线程已经有一段时间了。 [我对那个无能为力的评论可能是错误的,我已经有一段时间没有直接使用 Win32 了]。
更新:
根据您声明自己正在做什么的更新,我相当确定您在创建之前不允许连接。引用 http://msdn.microsoft.com/en-us/library/3d46645f(VS.80).aspx ,
To use a CAsyncSocket object, call its constructor, then call the Create function to create the underlying socket handle ... and for a client socket call the Connect member function.
至于为什么,我认为这增加了额外的复杂性,因为 Windows 需要在事件泵环境中执行异步套接字,因为它们不能阻塞主 GUI 线程。
在 UNIXy 环境中,要么没有事件线程(正常进程),要么网络操作只是手动转移到另一个线程(在 GUI 应用程序中)。
这很可能是很久以前在 WinSock 中做出的设计决定(可能是在 Windows 3.11 中,这是一个对执行异步操作有更多限制的环境)并且一直贯彻 [虽然这是我的推测,UNIX 套接字 API 有从来没有这种消息被泵送的异步行为,它总是倾向于使用 select()
或线程/进程。
进一步更新:
如果您关闭和/或删除了套接字对象,而该套接字对象上有待处理的操作,通常会发生该断言(不是异常)。对于您的情况,我建议它在您关闭它时仍在尝试进行连接。
然后当连接成功或失败时,回调被调用并且它无法在表中找到您的套接字。
这不是 MFC 的问题,是你 friend 的代码违反了约定。如果您执行连接(或任何异步操作),则必须在关闭套接字(或进一步处理它)之前等待成功或失败 - 在这种情况下,这意味着等待调用你的 OnConnect() 函数。
根据内存,您在创建异步套接字时调用了 create()
,然后所有其他事情都会响应到达消息队列的消息(即调用您的 OnXXX( )
函数)。像所有 Win32 GUI 东西一样,消息应该驱动程序(代码运行以响应消息)。这段代码看起来越来越像经典编码,其中程序驱动一切 - 这种方式很疯狂,因为您将让您的程序和异步套接字“线程”争夺控制权。
我已经有一段时间没看过它了,但您应该可以得到一个 CHATSRVR 示例程序,它会告诉您如何操作。
关于c++ - 我的 MFC 套接字代码中的 CAsyncSocket 断言问题和 "improper argument"错误背后的原因是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/800734/
我正在寻找一种无需子类化即可使用 CAsyncSocket 的方法。到目前为止,在我发现的所有示例和教程中,它们都是它的子类,我想避免使用它。 提前致谢 最佳答案 CAsyncSocket 旨在通过子
我正在使用 MFC CAsyncSocket 在多线程环境中进行一些网络通信。在尝试让接受的套接字接受传入数据几个小时后,我遇到了一个页面,该页面指出要调用 CAsyncSocket 的 OnRece
我有当前使用 CAsyncSocket 的控制台应用程序。我需要实现 SSL,所以经过一番搜索后我找到了这个项目:http://www.codeproject.com/Articles/3915/CA
所以,文档说: http://msdn.microsoft.com/zh-cn/library/ct7d990b(v=VS.80).aspx “Receive 返回接收到的字节数。如果连接已关闭,则返
如果我在调用 Connect 之后但在 OnConnect 之前删除 CAsyncSocket, CAsyncSocket 会使我的应用程序崩溃回调已被调用。 ASSERT(pSocket != NU
我有一个具有这种结构的服务器应用程序:有一个对象,称他为服务器,它在无休止的循环中监听和接受连接。我有来自 CAsyncSocket 的后代类,它覆盖了事件 OnReceive,称他为 ProxySo
我被要求为 friend 查看一些代码。 (由于 MFC 和很多糟糕的代码,我犹豫是对的,但他赢了……) 这是一个基于对话框的应用程序,使用了 CAsyncSocket。 问题表现为一些不间断的调试中
我是一名优秀的程序员,十分优秀!