我有一个套接字应用程序连接到服务器,然后收到缓冲区(大小已知),但在慢速网络上,应用程序不接收完整缓冲区这里是我的代码
var bytes = new byte[65000];
Socket.Receive(bytes);
答案 0 :(得分:4)
这很简单,你可以进行必要的修改
private byte[] ReadBytes(int size)
{
//The size of the amount of bytes you want to recieve, eg 1024
var bytes = new byte[size];
var total = 0;
do
{
var read = _connecter.Receive(bytes, total, size - total, SocketFlags.None);
Debug.WriteLine("Client recieved {0} bytes", total);
if (read == 0)
{
//If it gets here and you received 0 bytes it means that the Socket has Disconnected gracefully (without throwing exception) so you will need to handle that here
}
total+=read;
//If you have sent 1024 bytes and Receive only 512 then it wil continue to recieve in the correct index thus when total is equal to 1024 you will have recieved all the bytes
} while (total != size);
return bytes;
}
为了模拟这个,我有一个测试控制台应用程序,它生成了以下输出到调试控制台(带有一些线程和休眠)
Server Sent 100 bytes
Server Sent 100 bytes
Server Sent 100 bytes
Server Sent 100 bytes
Server Sent 100 bytes
Server Sent 12 bytes
Client Reads 512 bytes
Client Recieved 100 bytes
Client Recieved 200 bytes
Client Recieved 300 bytes
Client Recieved 400 bytes
Client Recieved 500 bytes
Client Recieved 512 bytes
我在Android应用程序上遇到了同样的问题
答案 1 :(得分:2)
方法Socket.Receive
将返回已读取的有效字节数。
您不能依赖缓冲区大小来获取完整的缓冲区读取,因为Receive
如果在一段时间内没有收到数据则会返回。将65000
视为最大,而不是有效缓冲区。
在快速网络上,您将获得buffer
快速填充,但在慢速网络数据包延迟将触发Receive
将其自身刷新到缓冲区阵列。
为了读取固定大小的缓冲区,您可能需要这样做:
public static byte[] ReadFixed (Socket this, int bufferSize) {
byte[] ret = new byte[bufferSize];
for (int read = 0; read < bufferSize; read += this.Receive(ret, read, ret.Size-read, SocketFlags.None));
return ret;
}
以上是作为Socket类的扩展方法创建的,以便更加舒适地使用。代码是手写的。
答案 2 :(得分:0)
这种方式无需设置初始读取大小,适合响应。
public static byte[] ReceiveAll(this Socket socket)
{
var buffer = new List<byte>();
while (socket.Available > 0)
{
var currByte = new Byte[1];
var byteCounter = socket.Receive(currByte, currByte.Length, SocketFlags.None);
if (byteCounter.Equals(1))
{
buffer.Add(currByte[0]);
}
}
return buffer.ToArray();
}