索引和计数必须引用缓冲区内的一个位置.参数名称:字节 [英] Index and count must refer to a location within the buffer. Parameter name: bytes

查看:44
本文介绍了索引和计数必须引用缓冲区内的一个位置.参数名称:字节的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,我收到此错误,请参阅附件 >> 索引和计数必须引用缓冲区内的一个位置.参数名称:字节

Hello guys im getting This error please see the attachment >> Index and count must refer to a location within the buffer. Parameter name: bytes

当我使用调试器时,我没有收到此错误,一切正常,我无法理解此错误是什么

When im using debugger i dont get this error and everything goes fine i cannot understand what this error is

这是我的服务器代码:

 IPEndPoint ipEnd = new IPEndPoint(IPAddress.Any, 27015);
            Socket sck = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
            sck.Bind(ipEnd);
            sck.Listen(100);

            Socket clientSocket = sck.Accept();

            string[] fNames = new string[3];
            fNames[0] = "01.jpg";
            fNames[1] = "02.jpg";
            fNames[2] = "03.jpg";

            string filePath = "D:\\";

            byte[] FilesCount = BitConverter.GetBytes(fNames.Count());


            clientSocket.Send(FilesCount);

            for (int i = 0; i < fNames.Count(); i++)
            {
                byte[] fileNameByte = Encoding.ASCII.GetBytes(fNames[i]);
                byte[] fileData = File.ReadAllBytes(filePath + fNames[i]);
                byte[] clientData = new byte[4 + fileNameByte.Length + fileData.Length];
                byte[] fileNameLen = BitConverter.GetBytes(fileNameByte.Length);

                fileNameLen.CopyTo(clientData, 0);
                fileNameByte.CopyTo(clientData, 4);
                fileData.CopyTo(clientData, 4 + fileNameByte.Length);

                clientSocket.Send(clientData);
            }

            clientSocket.Close();

和客户:

   Socket clientSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
        clientSock.Connect(IPAddress.Parse("46.49.70.30"), 27015);


        byte[] clientData = new byte[1024 * bt];
        string receivedPath = "D:/df/";

        byte[] FileQuantityByte = new byte[1024];
        clientSock.Receive(FileQuantityByte);
        int FileQuantity = BitConverter.ToInt32(FileQuantityByte, 0);

        for (int i = 0; i < FileQuantity; i++)
        {
            int receivedBytesLen = clientSock.Receive(clientData);

            int fileNameLen = BitConverter.ToInt32(clientData, 0);
            string fileName = Encoding.ASCII.GetString(clientData, 4, fileNameLen);

            //Console.WriteLine("Client:{0} connected & File {1} started received.", clientSock.RemoteEndPoint, fileName);

            BinaryWriter bWrite = new BinaryWriter(File.Open(receivedPath + fileName, FileMode.Append));
            bWrite.Write(clientData, 4 + fileNameLen, receivedBytesLen - 4 - fileNameLen);

            //Console.WriteLine("File: {0} received & saved at path: {1}", fileName, receivedPath);

            bWrite.Close();
        }

        clientSock.Close();

http://imageshack.us/f/202/errbk.jpg/

推荐答案

例外说明问题是什么:您的参数之一不是您认为应该是的.

The exception is telling exactly what the problem is: one of your parameters isn't what you think it should be.

clientData 的长度是多少?当您调用 Encoding.ASCII.GetString 时,fileNameLen 的值是多少?用于初始化您的 clientData 数组的 bt 的值是多少?

What is the length of clientData? What is the value of fileNameLen when you call Encoding.ASCII.GetString? What is the value of bt, which is used to initialize your clientData array?

如果在调试器中没有发生这种情况,那么在调用之前添加一些代码来输出 clientDatafileNameLen 的值.

If this doesn't happen in the debugger, then add some code to output the values of clientData and fileNameLen before the call.

一个问题是 clientSock.Receive 可能无法一次获取所有数据.如果您要发送一个特别大的文件,clientSock.Receive 可能会返回而不读取所有内容.作为 Socket.Receive 的文档说:

One problem is that clientSock.Receive might not get all of the data at once. If you're sending an especially large file, it's possible that clientSock.Receive will return without reading everything. As documentation for Socket.Receive says:

如果您使用的是面向连接的 Socket,Receive 方法将读取尽可能多的可用数据,最多可达缓冲区的大小.

If you are using a connection-oriented Socket, the Receive method will read as much data as is available, up to the size of the buffer.

可能不是所有数据都可用,或者缓冲区小于文件大小.为确保获得所有数据,您必须这样做:

It's possible that not all of the data is available yet, or that the buffer is smaller than the file size. To ensure that you get all of the data, you have to do this:

int totalBytesRead = 0;
int bytesRead = 0;
while ((bytesRead = clientSock.Receive(clientData, totalBytesRead,
    clientData.Length - totalBytesRead, SocketFlags.None)) != 0)
{
    totalBytesRead += bytesRead;
}

Receive 将在没有更多可用数据时返回 0.只有这样,您才能确定您已收到所有数据.

Receive will return 0 when there is no more data available. Only then can you be sure that you've received all of the data.

这篇关于索引和计数必须引用缓冲区内的一个位置.参数名称:字节的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆