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的成员变量保存,这样生命周期可以得以保证.
好吧,这件脑残事就这么结了.

时间: 2024-09-29 00:44:16

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

导出问题,在excel中某些字段不显示,还报不能读取的错误!!

问题描述 大神们给点指导呗! 解决方案 解决方案二:using(FileStreamfs=newFileStream(strExcelFileName,FileMode.OpenOrCreate)){System.IO.FileInfofile=newSystem.IO.FileInfo(strExcelFileName);System.Web.HttpContextcurContext=System.Web.HttpContext.Current;//让用户输入下载的本地地址curContex

Android模拟器接收UDP数据包的若干问题分析_Android

本文实例分析了Android模拟器接收UDP数据包的若干问题.分享给大家供大家参考,具体如下: android模拟器无法接收UDP数据包 代码如下: DatagramPacket pack = null; DatagramSocket mail_data = null; byte receiver[] = new byte[100]; try { pack = new DatagramPacket(receiver,receiver.length); mail_data = new Datagr

Android模拟器接收UDP数据包的若干问题分析

本文实例分析了Android模拟器接收UDP数据包的若干问题.分享给大家供大家参考,具体如下: android模拟器无法接收UDP数据包 代码如下: DatagramPacket pack = null; DatagramSocket mail_data = null; byte receiver[] = new byte[100]; try { pack = new DatagramPacket(receiver,receiver.length); mail_data = new Datagr

vc++2010用udp收double

问题描述 vc++2010用udp收double udp收double数如何解包,1个double收到8个字节的内存数-有没有什么可以用的函数 解决方案 可以直接memcpy复制到一个double数据变量 解决方案二: 直接强制类型转换就可以了double * d = (double *)&data[0]; //收到的数据不过要区分大端序和小端序,如果对方机器也是PC,不用考虑.

在maven更新依赖的时候,无法下载jar包,一直报missing

问题描述 在maven更新依赖的时候,无法下载jar包,一直报missing 我这边导公司的项目在maven更新依赖的时候,无法下载jar包,一直报missing,只能吧包的pom文件下载下来,请各位有经验的大神们帮我看看 解决方案 检查下网络环境,dns解析. 解决方案二: 网络没有问题,我就很奇怪的是为什么maven总是Missing artifact 解决方案三: 网络没有问题,我就很奇怪的是为什么maven总是Missing artifact 解决方案四: 我也是这种问题 不过可以手动下

发送数据-UDP数据包的发送顺序怎么确定?

问题描述 UDP数据包的发送顺序怎么确定? 我用UDP发送数据包,在连续发送的情况下,接收端怎么确定我的发送顺序? 有什么方法,还是在发送的时候要先添加序号? 解决方案 UDP 是无顺序的,先发的包不一定会先到,所以最好还是自己在协议中增加包的编号. 接收处理时,按无序的逻辑进行,这样就能正常完成数据的接收. 否则,就换 TCP 协议吧,它的顺序是可以保证的. 解决方案二: 自己编号自己编号自己编号 解决方案三: UDP没顺序,自己需要定义协议等来完成组包

nginx 编译-win7下编译nginx,添加h264.streaming包,编译报错

问题描述 win7下编译nginx,添加h264.streaming包,编译报错 如题, win7下编译nginx,添加h264.streaming包,编译报错 如何解决啊? 解决方案 具体编译错误信息是什么?这才好分析 解决方案二: http://www.07net01.com/program/310922.html 解决方案三: 解决方案四: 解决方案五: 使用最新版本的吧,不用自己再编译了

udp丢包 又是udp丢包

什么会导致udp丢包呢,我这里列举了如下几点原因: 1.调用recv方法接收端收到数据后,处理数据花了一些时间,处理完后再次调用recv方法,在这二次调用间隔里,发过来的包可能丢失.对于这种情况可以修改接收端,将包接收后存入一个缓冲区,然后迅速返回继续recv. 2.发送的包巨大丢包.虽然send方法会帮你做大包切割成小包发送的事情,但包太大也不行.例如超过30K的一个udp包,不切割直接通过send方法发送也会导致这个包丢失.这种情况需要切割成小包再逐个send. 3.发送的包较大,超过mtu

关于socket udp 数据包传输时间的问题

问题描述 关于socket udp 数据包传输时间的问题 两台计算机型号和千兆以太网卡全部相同,其中一台计算机作为服务器端,另一台作为客户端,两者通过socket建立连接(udp连接),客户端单次向服务器端发送一百万数据包(每个数据包大小为1024字节),服务器端只接收不回应,则共耗时15秒左右,但若设置服务器端将每次接收到的数据包再原路传输回去,客户端发送一个数据包,再接收到一个数据包,则客户端发送一百万包的时间为650秒,请问两者的时间为什么相差这么大? 解决方案 socket之udp传输