日期:2014-05-18  浏览次数:21007 次

C#的socket传输分包的问题
socket使用TCP协议进行点对点传输,当我在发送端发送一个长度为100万的字节数组时,在接收端不能一次就接收到,而是分了很多次进行接收,有时一次可以接收几万字节,有时一次可以接收几十万字节。
  我要问的问题:
  1.发送大数据量的数据时,是发送端自动将数据进行分段发送吗?
  2.为什么被自动分段后每次的发送量是变化的,这个变化有什么规律吗?
  3.Socket.SendBufferSize这个属性我并没有进行设置,默认是8192字节,但是分包后每次数据量都有几万、几十万,为什么没有出现异常?
  4.接收端的Socket.ReceiveBufferSize也没有进行设置,默认是8192字节,但每次可以接收的数据量都有几万、几十万,为什么没有出现异常?
  5.能解释一下socket缓存的工作原理吗?

------解决方案--------------------
探讨
引用:
有时一次可以接收几万字节,有时一次可以接收几十万字节
你是以什么方式得到这个数据的?


Socket.BeginReceive(……)

------解决方案--------------------
你用的是Socket.BeginReceive (byte[] buffer,
int offset,
int size,
SocketFlags socketFlags,
AsyncCallback callback,
Object state
)?
这个函数里的size就是你期望收到的数据大小
对方发过来的数据到达网卡后先放到TCP窗口中,然后从窗口复制到ReceiveBuffer,最后再从ReceiveBuffer复制到你提供的buffer中,因为你期望的size比较大,所以上面的过程重复了很多次
可能过了很长时间都没收到size大小的数据,系统可能以为不会再收到了(或者系统认为需要返回的时机到了,这个就要看系统的设计原理了),就将已经收到的数据返回给你
------解决方案--------------------
根据我使用下来的情况,
的确 不是我设多大就返回多少的
但是不是有一个返回值嘛 返回取得了多少
但是返回值<>byte长度时也不代表结束了
=0时可能后面还有数据

分包后每次数据量都有几万 这个是指每个包有几万字节?
还是指有几万包?你本地又是怎么取得的?
------解决方案--------------------
1.发送大数据量的数据时,是发送端自动将数据进行分段发送吗?
在数据进行tcp通信的时候,在发送端与接收都都会有一个缓冲栈。发送端先将数据放到缓冲栈里,然后再由缓冲栈向远程主机发送数据。接收端以相反的过程接收数据。至于数据是否进行分包(分段),分包的大小是多少,低层协议已经给你做了,上层应用程序不用关心。

2.为什么被自动分段后每次的发送量是变化的,这个变化有什么规律吗?
这个跟网络通信质量有关系。

3.Socket.SendBufferSize这个属性我并没有进行设置,默认是8192字节,但是分包后每次数据量都有几万、几十万,为什么没有出现异常?
你怎么知道 分包后每次数据量都有几万、几十万 ?

4.接收端的Socket.ReceiveBufferSize也没有进行设置,默认是8192字节,但每次可以接收的数据量都有几万、几十万,为什么没有出现异常?
这里只是缓冲区的数据大小,程序及时的将缓冲区里的数据取走,接收端又将接收到的数据填充到缓冲区中。

5.能解释一下socket缓存的工作原理吗?
不是很清楚。只知道有协议栈,发送和接收的数据先放在协议栈里,然后再改善或接收。
------解决方案--------------------
每次去的数据长度是不固定的,取决于你设的缓冲区大小,应该不会出现一次receive()后接受的长度超过缓冲区。在传文件时先发文件的长度,之后接受方循环接受,知道接受的总长度达到之前的长度就代表传完了。
不用考虑每次接了多少
------解决方案--------------------
探讨
”这个就要看系统的设计原理了“  能接收多少还能控制吗?

------解决方案--------------------
探讨
引用:
不知道楼主是怎么取数据的。
我一般先自己设置一个buffer,其实就是一个byte数组,然后从socket读数据,并放到这个byte数组里。

自定义一个buffer ,然后Socket.ReceiveFrom (Byte[], Int32, SocketFlags, EndPoint);缓冲区默认是8192字节,但一次ReceiveFrom 取得的数据是几万或者是几十万字节