Java и отправить файл через сокет - PullRequest
1 голос
/ 19 ноября 2011

Я пишу клиент-серверное приложение, которое будет отправлять XML-файл с клиента на сервер. У меня проблема с отправкой больших данных. Я заметил, что сервер может получить максимум 1460 байт. Когда я отправляю файл с более чем 1460 байтами, сервер получает только первые 1460 байтов и даже больше. В результате я получаю незавершенный файл. Вот мой код:

отправка клиента:

public void sendToServer(File file) throws Exception
{
    OutputStream output = sk.getOutputStream();     

    FileInputStream fileInputStream = new FileInputStream(file);
    byte[] buffer = new byte[1024*1024];
    int bytesRead = 0;

    while((bytesRead = fileInputStream.read(buffer))>0)
    {
        output.write(buffer,0,bytesRead);
    }

    fileInputStream.close();
}

Сервер получает:

public File getFile(String name) throws Exception
{
    File file=null;

    InputStream input = sk.getInputStream();

    file = new File("C://protokolPliki/" + name);
    FileOutputStream out = new FileOutputStream(file);

    byte[] buffer = new byte[1024*1024];

    int bytesReceived = 0;

    while((bytesReceived = input.read(buffer))>0) {
        out.write(buffer,0,bytesReceived);
        System.out.println(bytesReceived);
        break;
    }

    return file;
}

Кто-нибудь знает, что не так с этим кодом? Спасибо за любую помощь.

EDIT:

Ничего не помогает :(. Я гуглю об этом, и я думаю, что его значение, связанное с TCP MSS, равно 1460 байтов.

Ответы [ 4 ]

3 голосов
/ 19 ноября 2011

MTU ( Максимальная единица передачи ) для Ethernet составляет около 1500 байтов. Рассмотрите возможность отправки файла порциями (т.е. по одной строке за раз или по 1024 байта за раз).

Посмотрите, решит ли ваша проблема использование 1024 вместо 1024 * 1024 для байтового буфера.

3 голосов
/ 19 ноября 2011

Хотя это не относится к вашему вопросу, в документе API сказано, что FileInputStream.read возвращает -1 для конца файла. Вы должны использовать> = 0 для цикла while.

3 голосов
/ 19 ноября 2011

Убедитесь, что вы звоните flush() в потоках.


Прохожий спрашивает: не достаточно ли close()?

Вы связались с документами для Writer и информацией. в состояниях метода close() ..

Закрывает поток, сначала очищает его. ..

Таким образом, вы частично правы, ОТО, ОП явно использует OutputStream и документы для close() состояния:

Закрывает этот выходной поток и освобождает все системные ресурсы, связанные с этим потоком. Общий контракт закрытия заключается в том, что он закрывает выходной поток. Закрытый поток не может выполнять операции вывода и не может быть открыт повторно.

Метод закрытия OutputStream ничего не делает.

(Акцент мой.)

Итак, подведем итоги. Нет, вызов close() на обычном OutputStream не будет иметь никакого эффекта и может быть также удален компилятором.

2 голосов
/ 19 ноября 2011

В коде, выполняемом на стороне сервера, есть инструкция break в цикле while.Поэтому код в цикле будет выполняться только один раз.Удалите команду разрыва, и код должен нормально работать.

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