IOCP+UDP收包的时候:报0xC000000005,读取0x00000010错误的问题

简介:
最近发现我那简单得不再简单的IOCP+UDP的底层出错了,在大数据量的时候经常会报错,并且清一色都是报的:报0xC000000005,读取0x00000010错误.报错之后,整个程序的堆栈就全部破坏掉了.从发现问题到今日问题的解决,已经过去了一个月的时间.
唯一能够找到相关的资料只有: http://www.cppblog.com/HendricLee/archive/2008/07/29/57436.html
但是事实上,我的Overlapped都是复用的.因此,不大可能是此问题导致的.经过测试证明,也确实与此无关.
昨晚上又做了一系列的测试,结果到最后依旧是无果,百般无奈之下,只好问人,后面QQ好友Sagasarate告诉了我原委,我知道之后,只有两种感觉:想哭,想撞墙.
至于为什么,请看以下代码便知了.非常非常之低级的错误.
bool CUDPRecvSendThread::postRecvRequest(CUdpOverLappedRecv* pOverLappedRecv)
{
    ASSERT(pOverLappedRecv);
    if (pOverLappedRecv == NULL) return false;

    pOverLappedRecv->Reset();

    DWORD dwBytesRecv = 0;
    DWORD dwFlags = 0;
    int nSenderAddrSize = sizeof (sockaddr_in);

    int rc = 0;
    rc = ::WSARecvFrom(m_ServerSocket, pOverLappedRecv->GetWsaBuffer(), 1, &dwBytesRecv, &dwFlags,
        pOverLappedRecv->GetClientAddr(), &nSenderAddrSize,
        pOverLappedRecv->GetOverlapped(), NULL);

    if (rc == SOCKET_ERROR)
    {
        DWORD dwErrorCode = ::WSAGetLastError();
        if (dwErrorCode != WSA_IO_PENDING)
        {
            return false;
        }

    }


    return true;
}
请对照着MSDN看.
如果没看出来,那我来告诉你是为什么.
问题就在于WSARecvFrom的7个参数.
MSDN的描述:
lpFromlen  [in, out]

A pointer to the size, in bytes, of the "from" buffer required only if lpFrom is specified.

你会发现,这个参数是一个输入输出值.而WSARecvFrom投递的是一个异步的IOCP请求,故而,出了此方法(CUDPRecvSendThread::postRecvRequest)之后,nSenderAddrSize这个临时变量就会被回收.不出事才怪了.
好吧,这事就是我干出来的.今年竟是做一些脑残的事情.肿么了我这是.T_T
要解决这个问题,最好的办法就是把nSenderAddrSize作为CUdpOverLappedRecv的成员变量保存,这样生命周期可以得以保证.
好吧,这件脑残事就这么结了.

目录
相关文章
|
网络协议 网络架构
UDP包的大小与MTU
在进行UDP编程的时候,我们最容易想到的问题就是,一次发送多少bytes好?当然,这个没有唯一答案,相对于不同的系统,不同的要求,其得到的答案是不一样的,我这里仅对像ICQ一类的发送聊天消息的情况作分析,对于其他情况,你或许也能得到一点帮助:首先,我们知道,TCP/IP通常被认为是一个四层协议系统,包括链路层,网络层,运输层,应用层.
3947 0
|
19天前
|
缓存 负载均衡 网络协议
面试:TCP、UDP如何解决丢包问题
TCP、UDP如何解决丢包问题。TCP:基于数据块传输/数据分片、对失序数据包重新排序以及去重、流量控制(滑动窗口)、拥塞控制、自主重传ARQ;UDP:程序执行后马上开始监听、控制报文大小、每个分割块的长度小于MTU
|
5月前
|
存储 网络协议 数据处理
【Socket】解决UDP丢包问题
UDP(用户数据报协议)是一种无连接的传输层协议,因其不保证数据包的顺序到达和不具备内置重传机制,导致在网络拥塞、接收缓冲区溢出或发送频率过快等情况下容易出现丢包现象。为应对这些问题,可以在应用层实现重传机制、使用前向纠错码等方法。这些方法在一定程度上可以缓解UDP通信中的丢包问题,提高数据传输的可靠性和效率。
|
6月前
|
网络协议 算法 网络架构
Python网络编程之udp编程、黏包以及解决方案、tcpserver
Python网络编程之udp编程、黏包以及解决方案、tcpserver
|
6月前
【DPDK 】dpdk测试发udp包
【DPDK 】dpdk测试发udp包
|
缓存 网络协议 C++
|
缓存 网络协议 算法
【Python基础篇021】黏包现象丨udp的socket服务
【Python基础篇021】黏包现象丨udp的socket服务
10962 0
|
网络协议 PHP Python
推荐一些socket工具,TCP、UDP调试、抓包工具 推荐一些socket工具,TCP、UDP调试、抓包工具
还记得我在很久很久以前和大家推荐的Fiddler和Charles debugger么?他们都是HTTP的神器级调试工具,非常非常的好用。好工具能让你事半功倍,基本上,我是属于彻头彻尾的工具控。 假如有一天,你写“传统”的PHP有些累了,想玩玩socket了,搞搞python、NodeJS、GO之类的新兴语言或框架(当然我不是说这些语言不能写web),或者干脆就用PHP吧,事实上PHP5.
16629 0
|
网络协议 网络性能优化 安全
用户数据包协议(user datagram protocol)——UDP
用户数据报协议(User Datagram Protocol,UDP)是无连接不可靠传输层协议。它不提供主机到主机通信,它除了提供进程到进程之间的通信之外,就没有给 IP 服务增加任何东西。
1687 0