Индекс и количество должны ссылаться на местоположение в буфере. Имя параметра: байты - PullRequest
1 голос
/ 05 октября 2011

Здравствуйте, ребята, я получаю эту ошибку, пожалуйста, смотрите вложение >> Index and count must refer to a location within the buffer. Parameter name: bytes

enter image description here

Когда я использую отладчик я не получаю эту ошибку, и все идет хорошо, я не могу понять, что это за ошибка

это мой код сервера:

 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/

Ответы [ 2 ]

2 голосов
/ 05 октября 2011

Исключение точно говорит о том, в чем проблема: один из ваших параметров не такой, как вы думаете.

Какова длина clientData? Каково значение fileNameLen, когда вы звоните Encoding.ASCII.GetString? Какое значение bt используется для инициализации массива clientData?

Если этого не происходит в отладчике, добавьте некоторый код для вывода значений clientData и fileNameLen перед вызовом.

Одной из проблем является то, что clientSock.Receive может не получить все данные одновременно. Если вы отправляете особенно большой файл, возможно, что clientSock.Receive вернется, не прочитав все. В документации по Socket.Receive написано:

Если вы используете сокет, ориентированный на соединение, метод Receive будет считывать столько данных, сколько доступно, вплоть до размера буфера.

Возможно, что еще не все данные доступны или размер буфера меньше размера файла. Чтобы убедиться, что вы получите все данные, вы должны сделать это:

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

Receive вернет 0, когда больше нет доступных данных. Только тогда вы можете быть уверены, что получили все данные.

1 голос
/ 23 октября 2015

Решение простое. У меня похожая проблема на Encoding.UTF8.GetString(array[byte], index, array[byte].Length). Проблема в том, что метод будет TAKE с некоторым количеством байтов FROM с некоторой позицией в вашем массиве, поэтому вы должны занять не array[byte].Length, а меньше array[byte].Length - index.

Если в вашем массиве 10 элементов, и вы хотите взять все с 5-й позиции, вы не можете взять 10 элементов.

Итак, снова - Encoding.UTF8.GetString(array[byte], FROM, TAKE)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...