Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何从套接字读取数据以附加缓冲区_C#_Arrays_.net_Sockets_Tcp - Fatal编程技术网

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中的代码被调用了很多次。读取一些字节并相应地进行切换是错误的。