Отправка jpg файла по Http

Я пытаюсь написать http-сервер, который принимает изображения. Таким образом мне удалось передать текстовые файлы или простой текст. Но когда дело доходит до файла jpeg, переданный становится недоступным.

Сторона клиента:

        WebRequest request = WebRequest.Create("http://localhost:8080");
        request.Method = "POST";
        byte[] byteArray = System.IO.File.ReadAllBytes(path);
        request.ContentType = "image/jpeg";
        request.ContentLength = byteArray.Length;
        Stream dataStream = request.GetRequestStream();
        dataStream.Write(byteArray, 0, byteArray.Length);
        dataStream.Close();

Сторона сервера:

        HttpListenerContext context = listener.GetContext();
        HttpListenerRequest request = context.Request;
        StreamReader reader = new StreamReader(request.InputStream,request.ContentEncoding);
        Console.WriteLine("Client data content type {0}", request.ContentType);
        String Data = reader.ReadToEnd();
        byte[] imagebuffer = System.Text.Encoding.UTF8.GetBytes(Data);
        System.IO.File.WriteAllBytes(path, imagebuffer);

Когда я пробую это с файлом .txt, длина массива байтов с каждой стороны не меняется, и файл на стороне сервера доступен для чтения. Но с jpg длина массива другая. Я предполагаю, что это вызывает проблему. Что я могу сделать, чтобы избежать этого? или есть альтернативы?

Изменить: заменено «StreamReader» на «BinaryReader», теперь работает нормально. выглядит как;

        BinaryReader reader = new BinaryReader(request.InputStream, request.ContentEncoding);
        byte[] imagebuffer = reader.ReadBytes((int)request.ContentLength64);
        System.IO.File.WriteAllBytes(path, imagebuffer);

person aldewine    schedule 05.03.2013    source источник


Ответы (3)


Сообщение HTTP двоичных данных передает двоичные данные, а не строки. Ваш код на стороне сервера неправильно анализирует JPG как какую-то строку. Используйте объект Stream и считывайте поток в массив байтов без использования объекта StreamReader.

person Vetsin    schedule 05.03.2013

Вы портите данные, кодируя их с помощью UTF8. Это не место для использования строки.

Сервер должен сначала проверить заголовок ContentLength, а затем прочитать это количество байтов, используя либо BinaryReader.ReadBytes, либо Stream.Read. Однако обязательно ищите исключения, на случай, если что-то не совпадет.

В качестве еще одного совета я бы предложил, чтобы сервер считывал данные порциями (по несколько килобайт за раз) вместо того, чтобы пытаться сохранить все данные в памяти перед записью на диск. Вы никогда не знаете, насколько большой файл может быть загружен.

person YotaXP    schedule 05.03.2013

Я полагаю, вы хотите преобразовать двоичный поток в строку с кодировкой Base64, а затем получить байты из этого на сервере.

Клиент

var jpgBytes = File.ReadAllBytes(path);
var encodedString = Convert.ToBase64String(jpgBytes);
var encodedBytes = new byte[encodedString.Length * sizeof(char)];
System.Buffer.BlockCopy(encodedString.ToCharArray(), 0, bytes, 0, bytes.Length);

var requestStream = request.GetRequestStream();
requestStream.Write(encodedBytes, 0, encodedBytes.length);

Сервер

var reader = new StreamReader(request.InputStream,request.ContentEncoding); 
var base64String = reader.ReadToEnd();
var jpg = Convert.FromBase64String(base64String);
person Jason    schedule 05.03.2013
comment
В этом нет необходимости, поскольку HTTP поддерживает передачу двоичных файлов. Не должно быть задействовано base64. - person Vetsin; 05.03.2013