C# 如何从套接字读取数据以附加缓冲区
因此,我试图将一个图像从我的客户端发送到我的服务器,我将整个图像作为一个整体发送,这意味着我没有将其拆分为块,我只是按原样发送整个字节数组 客户端C# 如何从套接字读取数据以附加缓冲区,c#,arrays,.net,sockets,tcp,C#,Arrays,.net,Sockets,Tcp,因此,我试图将一个图像从我的客户端发送到我的服务器,我将整个图像作为一个整体发送,这意味着我没有将其拆分为块,我只是按原样发送整个字节数组 客户端 private void SendImage(byte[] opcode, byte[] length, byte[] payload) { var packet = new byte[payload.Length + length.Length + 1]; Array.Copy(opcode, 0, packet, 0, 1);
private void SendImage(byte[] opcode, byte[] length, byte[] payload)
{
var packet = new byte[payload.Length + length.Length + 1];
Array.Copy(opcode, 0, packet, 0, 1);
//Set the length
Array.Copy(length, 0, packet, 1, length.Length);
Array.Copy(payload, 0, packet, 5, payload.Length);
_clientSocket.Send(packet);
}
这发送得很好,我正在使用操作码0x15
,服务器会将其解释为“有图像传入”。长度是我使用的payload.length
var length=BitConverter.GetBytes(myImage.length)代码>
所以它占用了4个字节
因此,我的数据包结构如下所示:操作码(1字节)、长度(4字节)、有效负载(imageBytes)
这个方法工作得很好,发送时没有任何问题。我只包含了它的代码,以便下一部分有意义
服务器
private byte[] _buffer = new byte[1024];
private void ReceiveCallback(IAsyncResult ar)
{
var client = (Socket)ar.AsyncState;
int received = client.EndReceive(ar);
//Temporary buffer
var dataBuf = new byte[received];
Array.Copy(_buffer, dataBuf, received);
switch (dataBuf[0])
{
//Received image
case 0x15:
//Read the packet header and check the length of the payload
var length = BitConverter.ToInt32(dataBuf.Skip(1).Take(4).ToArray(), 0);
//This will hold the bytes for the image
var imageBuffer = new byte[length];
//First incoming packet payload (image bytes)
var imgData = dataBuf.Skip(5).ToArray();
//Copy that into the buffer
Array.Copy(imgData, 0, imageBuffer, 0, imgData.Length);
var pos = imgData.Length;
//Keep reading bytes from the incoming stream
while (dataBuf.Length > 0)
{
imgData = new byte[1024];
client.Receive(imgData);
Array.Copy(imgData, 0, imageBuffer, pos, dataBuf.Length);
pos += 1024;
}
//This takes the bytes and creates a bitmap from it
AnotherViewModel.SetImage(imageBuffer);
break;
default:
Debug.WriteLine("Wat");
break;
}
client.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), client);
}
我面临的问题是,我不知道如何继续将传入数据附加到imageBuffer
,因为我希望接收完整的图像,而不仅仅是前4个字节,而通过while循环,我目前得到了这个异常
目标数组不够长。检查目的索引和长度,以及
数组的下界
在这一行Array.Copy(imgData,0,imageBuffer,pos,dataBuf.Length)代码>
如何正确读取客户端发送到服务器的整个图像?您可能需要检查实际接收的字节数,您似乎假设它是1024的完美倍数,但情况可能并非如此。pos变量只能按实际接收的长度而不是1024(最大大小)递增。我的蜘蛛感觉告诉我,这是最后一个让你陷入麻烦的块。我不是故意粗鲁,但你可能需要设计一个更好的通信协议。依我拙见,在网络流上计算字节是不好的。看看FTP是如何工作的。在客户机中发送整个映像并不能保证它会像这样到达服务器。它肯定会在tcpip堆栈上下各自为政。服务器正在异步接收,所以我猜ReceiveCallback中的代码被调用了很多次。读取一些字节并相应地进行切换是错误的。