Сокеты Java - файлы, передаваемые одновременно с другими данными через одно соединение - PullRequest
4 голосов
/ 25 января 2010

У меня есть многопоточный сервер, который обрабатывает запросы клиентов и создает новые потоки для каждого подключенного. Это прекрасно работает, и я могу отправлять «текстовые» сообщения на сервер и обратно без проблем. Как система чата.

Теперь я имею в виду способ отправки файлов через эти клиентские соединения на сервер, но каждый отдельный пример, который я вижу в java, всегда имеет жестко запрограммированное имя файла на стороне сервера / клиента - но я хочу установить свой собственный для гибкости. И я был бы рад, если бы он не только мог не только получать файлы, но и одновременно получать «текстовые» сообщения через один и тот же порт.

У меня есть идея, по которой порт «текстового» сообщения, который у меня есть в данный момент, сообщает серверу, что файл будет отправлен с клиента, затем сервер открывает порт «передачи файлов», просто для передачи файлов. , Таким образом, «текстовый» порт может указывать имя файла и т. Д. А другой порт может отправлять файлы довольно счастливо, без перерыва.

Кто-нибудь знает лучший способ сделать это, хотя? Я действительно не хочу использовать два порта, это кажется немного грязным. Я бы предпочел создать отдельный поток на стороне сервера, чтобы заниматься передачей файлов, а также одновременно обрабатывать «текстовые» сообщения, если это вообще возможно?

Заранее спасибо, надеюсь, я был достаточно ясен:)

Ответы [ 5 ]

4 голосов
/ 25 января 2010

Конечно, это легко. Вам просто нужно сначала указать тип сообщения. Либо с байтом, либо со строкой текста.

Самый простой способ - использовать один байт:

//to send
Socket s = ...
OutputStream os = s.getOutputStream();
if(messageIsText()){
  os.write(0);
  //send text
else{
  os.write(1); 
  //send file
}

тогда на вашем сервере вы можете сделать это:

Socket s = serverSocket.accept();
InputStream in = s.getInputStream();
int firstbyte = in.read();
if(firstbyte = 0){
   //read text
}
else{
   //read file
}

Теперь, это не очень гибко, но есть много вещей, которые вы можете сделать. Я бы порекомендовал вам прочитать RFC 2616 , это спецификация для HTTP. Вам не нужно читать все это, а достаточно просто написать простой веб-сервер. На самом деле это действительно просто (HTTP - очень простой протокол в ядре, хотя сейчас у него много расширенных функций)

Если вы действительно хотите научиться сетевому программированию, попробуйте написать HTTP-сервер. Это может показаться пугающим, но не волнуйтесь, на самом деле это совсем не сложно.

1 голос
/ 25 января 2010

Похоже, вы заново изобретаете FTP. Возможно, вы захотите взглянуть на FTP-серверы, реализованные на Java. WebDAV также.

0 голосов
/ 11 февраля 2011

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

Для этого классного чередования вы можете попробовать либо библиотеку google protobuf - у них есть хороших примитивов для чтения / записи небольших кусков данных в поток, либо простой / старый Object (In | Out ) putStream .

0 голосов
/ 25 января 2010

Что вы описываете, в значительной степени, как работает FTP. И да, это грязно, особенно в части, где сервер открывает порт, потому что это просто не работает в этом веке брандмауэров и NAT. Таким образом, FTP пришлось добавить «пассивный режим», когда клиент открывает дополнительный порт.

Но на самом деле нет причин иметь отдельные порты. Почему бы просто не иметь один вид текстового сообщения, которое объявляет «вот идет файл», и отправить файл сразу после этого на тот же порт?

0 голосов
/ 25 января 2010

Разбейте файл на части и отправьте их по «обычной» линии.

Что-то ссылка:

  • текстовое сообщение
  • стартовый файл (id <- номер, придуманный клиентом, имя файла) </li>
  • кусок файла (id, с несколькими байтами в байте [])
  • конечный файл (id)

сервер получает стартовый файл и начинает сохранение новой структуры: * ID клиента * придуманный идентификатор (и название почему бы и нет!)

затем с каждым фрагментом файла добавляйте байты (возможно, запись на диск или что-то в этом роде)

Конечный файл сказал бы: хорошо, промой и закрой!

Сервер может сохранять файлы на карте, сопоставляя объект Key (clientid + fileid) с временной структурой.

...