套接字性能技术示例(SocketAsyncEventArgs),客户端发送的数据包较大,服务器端不能接受完全的问题

Xuon 2010-07-22 08:39:35
套接字性能技术示例(SocketAsyncEventArgs):http://code.msdn.microsoft.com/nclsamples/Wiki/View.aspx?title=Socket%20Performance

发送大小为40000多的数据(byte[]类型),不同的电脑测试,部分电脑上不能接受到全部的数据。

找了两天,没找到导致问题的原因。

PS:客户端是用的Socket发的数据,用的TCP。

不知道大家有什么见解,特来请教一下。
...全文
812 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
尐孑 2010-08-31
  • 打赏
  • 举报
回复
向大家学习
悔说话的哑巴 2010-08-25
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 gxj760998 的回复:]
要制定一个简单的协议,最好有点验证!
在发送的数据中存有数据长度信息。。。
这个就是协议的简单化版本了,你如果考虑的细致点,就会发现这有漏洞。
比如:如果发送的数据接收错位了,你解析的数据长度超过几百M字节?
采用固定头尾的方式+数据长度范围认证,能比较有效的解决这样的问题。
[/Quote]
这个方法不错
gxj760998 2010-08-25
  • 打赏
  • 举报
回复
要制定一个简单的协议,最好有点验证!
在发送的数据中存有数据长度信息。。。
这个就是协议的简单化版本了,你如果考虑的细致点,就会发现这有漏洞。
比如:如果发送的数据接收错位了,你解析的数据长度超过几百M字节?
采用固定头尾的方式+数据长度范围认证,能比较有效的解决这样的问题。
Xuon 2010-08-11
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 cgabriel 的回复:]

引用 8 楼 n_ithero 的回复:

引用 7 楼 cgabriel 的回复:

发包前在封包的头部标上长度,循环读取


已经改成循环读取了,循环读取还是有时会出现数据接收不完全的情况。

比如:
发送的byte数组的大小为30000多,有时只接收到20000多或者更少,有时又能接收到完整的。只是这次在Windows7和XP上测试的效果是一样的。

之前的方法是设……
[/Quote]

现在用的方法是在发送的数据中存有数据长度信息,确保循环读取完成再使用的。
接下来得处理一下并发的问题。
另外就是客户端发送数据的时候意外断开等特殊情况。
CGabriel 2010-08-09
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 n_ithero 的回复:]

引用 7 楼 cgabriel 的回复:

发包前在封包的头部标上长度,循环读取


已经改成循环读取了,循环读取还是有时会出现数据接收不完全的情况。

比如:
发送的byte数组的大小为30000多,有时只接收到20000多或者更少,有时又能接收到完整的。只是这次在Windows7和XP上测试的效果是一样的。

之前的方法是设置足够大的接收缓冲区,一次接收数据,XP上测试没……
[/Quote]

很明显是你的循环读取有问题,是否考虑到一切的情况,例如封包可能在任意的地方切开。。。
Xuon 2010-08-08
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 cgabriel 的回复:]

发包前在封包的头部标上长度,循环读取
[/Quote]

已经改成循环读取了,循环读取还是有时会出现数据接收不完全的情况。

比如:
发送的byte数组的大小为30000多,有时只接收到20000多或者更少,有时又能接收到完整的。只是这次在Windows7和XP上测试的效果是一样的。

之前的方法是设置足够大的接收缓冲区,一次接收数据,XP上测试没发现问题。Windows 7与XP通信会有问题,Windows 2003与Windows 7通信也会有问题。

我用的VS2010旗舰版。
CGabriel 2010-08-06
  • 打赏
  • 举报
回复
发包前在封包的头部标上长度,循环读取
Xuon 2010-08-04
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 gxj760998 的回复:]

没有看明白你这个改进代码与你的问题存在什么关系。
缓冲区本身有几种:系统的,NET程序的。
缓冲区本身如果填满了,会造成丢失数据啊?这个时候,应该暂停接收才对。对方此时发送不了。
[/Quote]

实际测试发现,即使改了前面提到的缓冲区大小,还是有时会出现接收数据不完全的问题(不稳定)。

现在用的方案是,将缓冲区设置成一个较小的值,发来的数据超过这个值就分几次接收,之后组合成一个完整的数据再使用。
gxj760998 2010-07-23
  • 打赏
  • 举报
回复
没有好的通讯协议支持。
在大数据量的通信环境下,要考虑双方的发送速度、接收处理速度。
一般情况下,都需要在TCPIP的基础上,增加自己的协议,单靠TCPIP,解决不了问题。
tyg111 2010-07-23
  • 打赏
  • 举报
回复
正在关注中
gxj760998 2010-07-23
  • 打赏
  • 举报
回复
没有看明白你这个改进代码与你的问题存在什么关系。
缓冲区本身有几种:系统的,NET程序的。
缓冲区本身如果填满了,会造成丢失数据啊?这个时候,应该暂停接收才对。对方此时发送不了。
Xuon 2010-07-23
  • 打赏
  • 举报
回复
private void ProcessAccept(SocketAsyncEventArgs e)
{
Interlocked.Increment(ref m_numConnectedSockets);
Console.WriteLine("Client connection accepted. There are {0} clients connected to the server",
m_numConnectedSockets);

// Get the socket for the accepted client connection and put it into the
//ReadEventArg object user token
SocketAsyncEventArgs readEventArgs = m_readWritePool.Pop();
((AsyncUserToken)readEventArgs.UserToken).Socket = e.AcceptSocket;

// As soon as the client is connected, post a receive to the connection
bool willRaiseEvent = e.AcceptSocket.ReceiveAsync(readEventArgs);
if(!willRaiseEvent){
ProcessReceive(readEventArgs);
}

// Accept the next connection request
StartAccept(e);
}

上面的是原来的代码,e.AcceptSocket使用的是默认值8192。而Server构造函数中传来了一个的参数receiveBufferSize并未用来设置此处e.AcceptSocket的ReceiveBufferSize的值。

添加如下代码:

e.AcceptSocket.ReceiveBufferSize = m_receiveBufferSize;


即可解决问题。

“套接字性能技术示例”还有其它不足或者说遗漏,我会整理一篇文章出来。

17,741

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 .NET Framework
社区管理员
  • .NET Framework社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧