关键词:dotnet, socket, asynchronous 异步, tcp
在上次参加趋势的百万程序大赛的时候,我负责的socket通讯部分出了一件怪事:当大量传输数据包的大小在一定大小以上(一般是1500到2000)的时候,会在一定时间之后出现数据包的解包错误。
传输方式是TCP, 传输的是序列化后的对象,传输格式是 byte[4]作为对象长度+序列化后的对象本身,处理方法是 接受方读取对象长度后建立对应大小的byte[]一次读清数据包。
在小数据包时没有任何问题,但是在传输大到一定程度后的一段时间后(当时的情况是大约10秒不到)会出现无法 反序列化,即传输错误。
原本我们调试的基准是 基于TCP的传输是可靠的,所以一直在检查程序的逻辑错误。但是最后发现,问题在于, 回调函数 ReceiveDone() 在缓冲区并未完全读满以后就被调用了,导致最后读取的一部分为 0,数据反序列化失败。
问题是:缓冲区的控制 显然是交给dotnet的,所以基本肯定是dotnet的问题。感觉上似乎是写缓冲区的速度没有跟上传输的速度,不过不大可能啊……
发生的环境:局域网,机器配置服务器(接收端)是64位机(Athlon64),发送端32位机。不知道和这又没有关系
但是这几天我试图重现这个问题,发现本机上不太好重现。可能是处理速度够快。
先把这个问题放在这里,如果有人碰到了同样的问题,还请多多交流。
感谢Gas确定了问题的所在。
UPDATE: 我不知道是不是我当时犯了一个糊涂的错误——没有用循环来读取recv的内容,而且认为recv肯定是要多少就读了多少……
不过我现在不会反这个错误了……
在上次参加趋势的百万程序大赛的时候,我负责的socket通讯部分出了一件怪事:当大量传输数据包的大小在一定大小以上(一般是1500到2000)的时候,会在一定时间之后出现数据包的解包错误。
传输方式是TCP, 传输的是序列化后的对象,传输格式是 byte[4]作为对象长度+序列化后的对象本身,处理方法是 接受方读取对象长度后建立对应大小的byte[]一次读清数据包。
在小数据包时没有任何问题,但是在传输大到一定程度后的一段时间后(当时的情况是大约10秒不到)会出现无法 反序列化,即传输错误。
原本我们调试的基准是 基于TCP的传输是可靠的,所以一直在检查程序的逻辑错误。但是最后发现,问题在于, 回调函数 ReceiveDone() 在缓冲区并未完全读满以后就被调用了,导致最后读取的一部分为 0,数据反序列化失败。
问题是:缓冲区的控制 显然是交给dotnet的,所以基本肯定是dotnet的问题。感觉上似乎是写缓冲区的速度没有跟上传输的速度,不过不大可能啊……
发生的环境:局域网,机器配置服务器(接收端)是64位机(Athlon64),发送端32位机。不知道和这又没有关系
但是这几天我试图重现这个问题,发现本机上不太好重现。可能是处理速度够快。
先把这个问题放在这里,如果有人碰到了同样的问题,还请多多交流。
感谢Gas确定了问题的所在。
UPDATE: 我不知道是不是我当时犯了一个糊涂的错误——没有用循环来读取recv的内容,而且认为recv肯定是要多少就读了多少……
不过我现在不会反这个错误了……