Отправка больших файлов через сокеты на отдельных компьютерах - PullRequest
0 голосов
/ 01 ноября 2018

Я создал базовую программу клиент-сервер, которая передает файл с сервера на клиент. Поскольку размер файла составляет около 500 МБ, сервер передает файл в виде кусков байтов клиенту через объект DataOutputStream. Хотя эта логика работает нормально, когда клиент и сервер работают на одном компьютере, она не работает, когда две программы работают на разных компьютерах (оба компьютера находятся в одной сети, и я отключил брандмауэр для обоих)

При работе на отдельных компьютерах проблема заключается в том, что передается несколько байтов

Логика сервера:

byte byteArr[] = new byte[1024];
while((c=fileInputStream.read(byteArr, 0, 1024) != -1))
{
    dataOutputStream.writeBoolean(true);
    dataOutputStream.flush();
    dataOutputStream.write(byteArr, 0, 1024);
    dataOutputStream.flush();
}
 /*When running on different computers, after a few hundred iterations 
   it just stops looping the following lines are never executed*/
dataOutputStream.writeBoolean(false);
System.out.println("Transfer complete");

Клиентская логика

byte byteArr[] = new byte[1024];
while(dataInputStream.readBoolean())
{
     dataInputStream.read(byteArr, 0, 1024);
     fileOutputStream.write(byteArr, 0, 1024);
}

1 Ответ

0 голосов
/ 01 ноября 2018

A read(buf, 0, 1024) вызов , а не гарантированно читает ровно 1024 байта. Это вызывает ошибки в обеих частях кода:

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

Чтобы решить эту проблему, вы можете:

  • отправить размер файла (если известен) перед отправкой файла, затем продолжайте читать, пока не прочитаете столько байтов.

  • или отправьте c (размер куска) вместо одного логического значения, затем используйте dataInputStream.readFully(), чтобы убедиться, что будет прочитано много байтов.

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