Как реализовать передачу файлов с помощью сокетов Java? - PullRequest
2 голосов
/ 21 апреля 2010

Я работаю над реализацией чата с сокетами Java. Я сосредоточился на нескольких функциях, таких как аутентификация, чат одного человека и групповой чат. Я думал о добавлении функциональности передачи файлов, и мне интересно, что хорошего в этом. Должен ли я иметь отдельный сокет на сервере с другим портом прослушивания только для передачи файлов? Прямо сейчас потоки ввода и вывода, которые я получаю из сокета сервера, связаны соответственно с объектами Scanner и PrintWriter, поэтому мне сложно использовать это для передачи файлов.

Любые модели, которые вы, ребята, могли бы порекомендовать или дать мне хорошие рекомендации, очень ценятся.

Спасибо

ZeKoU

Ответы [ 2 ]

3 голосов
/ 21 апреля 2010

Ну, FTP создает новый сокет для каждой передачи файла. Обратите внимание, что соединение может быть установлено на тот же порт, который используется для чата, но с другим диалоговым окном инициализации.

0 голосов
/ 07 февраля 2012

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

Если вам действительно нужно отправить файл на чистом Java. Вот один из способов, основанный на моем старом проекте. Однако обратите внимание, что есть некоторые издержки сериализации, однако большая часть этого может быть удалена путем использования эквивалентов NIO, как обсуждено здесь , или вы можете пойти немного дальше и использовать Zero Copy , что позволяет вам сказать ОС для копирования файлов напрямую в сокет без каких-либо посреднических копий. Это работает только с файлами, но не с другими данными.

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

//Send file (Server)
//Put this in a thread
Socket socket = new Socket(destinationIP, destinationPort);
ObjectOutputStream sender = new ObjectOutputStream(socket.getOutputStream());
sender.writeObject(dataToSend);

//Receive File (Client)
//Kick off a new thread to receive the file to preserve the liveness of the program
ServerSocket serverSocket = new ServerSocket(ListenPort);
socket = new Socket();
while (true) {
        new Thread(new TCPReceiver(socket)).start();
}

//Receive file thread TCPReceiver(Socket socket)
//Get the stream where the object is to be sent
ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());

/*  Where type is the type of data you send... String or anything really...
    read part of the file into something and send it then at this end use the same data                                                       
    type to recieve it and it will magically pull the entire object across.
*/
while(fileIsIncomplete){
    type recievedData = (type) objectInputStream.readObject();
    //Reconstruct file
}

Надеюсь, вам этого хватит, чтобы запустить и быстро запустить отправителя файлов:)

Редактировать: Удалено бессмысленное утверждение. Добавлена ​​нативная точка и упоминание нулевой копии.

...