Полный пример передачи файла на основе протокола сокета Java, завершен на основе связи TCP.
В дополнение к бинарному переносу файлов на основе TCP, некоторые навыки программирования Java Swing, демонстрационная программа
Основные функции реализованы следующим образом:
Во -первых, давайте посмотрим на отношения между всем классом купола:
Ниже приведено подробное объяснение функций и реализаций кода каждого класса в соответствии с вышеуказанным рисунком:
Серверная сторона:
Функция класса FileTransFerserver первой для создания сервера на порту 9999 и
Начните слушать соединение. Соответствующие коды следующие:
Private void Starterver (int port) {try {serversocket = new Serversocket (port); System.out.println («Сервер запускается в порту:» + port); while (true) {socket client = serversocket.accept (); // Заблокировано и ожидание Socket System.out.out.println («только что подключено к» + client.getRemoteSocketAddress ()); FileCeiveTask task = new FileCeiveTask (клиент); bar.setValue (0); // сбросить это теперь task.addpropertychangelistener (new PropertyChangelistener () {public void PropertyChange (PropertyChangeEvent evt) {if ("Progress" .equals (evt.getPropertyName ())) {bar.setValue ((integer) evt.getNewValue ());}}});); task.execute (); }} catch (ioException e) {e.printstacktrace (); }}Что касается PropertyChangelistener, Java предоставляет очень мощный класс инструментов для мониторинга изменений данных в любой модели бобов. Программа реализует
Собственные изменения в сфере значения свойства SwingWorker Изменены значения события, а затем обновите JProgressBar
Объект экземпляра, осознает обновление пользовательского интерфейса. Полный исходный код класса FileTransFerserverer заключается в следующем:
пакет com.gloomyfish.socket.tutorial.fileTransfer; импортировать java.awt.borderlayout; импортировать java.awt.flowlayout; импортировать java.awt.event.actionevent; импортировать java.awt.event.actionlistener; Импорт java.beans.propertychangeevent; Импорт java.beans.propertychangelistener; импортировать java.io.ioexception; импортировать java.net.serversocket; импортировать java.net.socket; импортировать javax.swing.boxlayout; Импорт javax.swing.jbutton; импортировать javax.swing.jframe; импортировать javax.swing.joptionpane; импортировать javax.swing.jpanel; Импорт javax.swing.jprogressbar; открытый класс FileTransFerserver Extends JFrame реализует ActionListener { / ** * * / public final Static String start_svr = "start"; public final Static String shut_down_svr = "shut Down"; публичная окончательная статическая строка end_flag = "eof"; Частный статический конечный длинный SerialVersionuid = 1L; Private Serversocket Serversocket; Частный Jbutton startbtn; Частный бар JProgressbar; public fileTransFerserver () {super ("файловый сервер"); initComponent (); setUplistener (); } private void setUplistener () {startBtn.addactionListener (this); } private void initComponent () {startBtn = new jbutton (start_svr); JPanel ProgressPanel = new jPanel (); progresspanel.setlayout (new Boxlayout (ProgressPanel, boxlayout.y_axis)); bar = new jprogressbar (); bar.setminimum (0); bar.setmaximum (100); ProgressPanel.Add (бар); getContentPane (). SetLayout (new BorderLayout ()); Jpanel btnpanel = new jpanel (new flowlayout (flowlayout.right)); btnpanel.add (startbtn); getContentPane (). Add (btnpanel, borderlayout.south); getContentPane (). Add (ProgressPanel, Borderlayout.center); } private void Startererver (int port) {try {serversocket = new Serversocket (port); System.out.println («Сервер запускается в порту:» + port); while (true) {socket client = serversocket.accept (); // Заблокировано и ожидание Socket System.out.out.println («только что подключено к» + client.getRemoteSocketAddress ()); FileCeiveTask task = new FileCeiveTask (клиент); bar.setValue (0); // сбросить это теперь task.addpropertychangelistener (new PropertyChangelistener () {public void PropertyChange (PropertyChangeEvent evt) {if ("Progress" .equals (evt.getPropertyName ())) {bar.setValue ((integer) evt.getNewValue ());}}});); task.execute (); }} catch (ioException e) {e.printstacktrace (); }} public void showeccess () {bar.setValue (100); Joptionpane.showmessageDialog (это, "файл успешно получил!"); } @Override public void actionPerformed (actionEvent e) {if (start_svr.equals (e.getActionCommand ())) {Thread startThread = new Thread (new Runnable () {public void run () {starterver (9999);}}); startthread.start (); startBtn.setEnabled (false); } else if (shut_down_svr.equals (e.getActionCommand ())) {} else {// ничего не делать ...}} public static void main (string [] args) {fileTransFerServer Server = new FileTransFerServer (); server.setDefaultCloseoPeration (jframe.exit_on_close); Server.setSize (400, 400); Server.SetReSizable (false); server.setvisible (true); }} FileCeiveTask - это класс приема файла на стороне сервера:
Сначала получите имя файла и размер файла из установленного потока TCP, а затем начните принимать байты содержимого файла
И записать в созданный поток объекта файла и, наконец, убедитесь, что размер файла равен написанному байтовому потоку
Наконец, отправьте сообщение отправителю файла, чтобы сообщить другой стороне, что передача файла завершена, и поток TCP может быть закрыт.
Полный исходный код этого класса заключается в следующем:
пакет com.gloomyfish.socket.tutorial.fileTransfer; Импорт java.io.bufferedOutputStream; Импорт java.io.bufferedOutputStream; импортировать java.io.datainputstream; Импорт java.io.file; Импорт java.io.fileOutputStream; импортировать java.io.outputstreamwriter; импортировать java.net.socket; импортировать javax.swing.swingworker; открытый класс FileReceivekask Extends SwingWorker <Integer, Object> {Private Socket _Msocket; public fileReceiveTask (stocket client) {this._msocket = client; } @Override Protected integer doInbackground () бросает exception {// Получить мета -информацию DataInputStream input = new DataInputStream (_msocket.getInputStream ()); String fileName = input.Readutf (); int fileLength = (int) input.readlong (); // количество файлов общего файла байта = новый файл ("c: // users // Fish // Загрузки" + file.separator + filename); BufferedOutputStream output = new BufferedOutputStream (New FileOutputStream (File)); System.out.println ("Полученный файл name =" + filename); System.out.println ("Полученный файл size =" + filelength/1024 + "kb"); // начать получать содержимое файла и написать их byte [] content = new Byte [2048]; int offset = 0; int numReadBytes = 0; while (offset <fileLength && (numReadBytes = input.read (content))> 0) {output.Write (content, 0, numReadBytes); float precent = 100.0f * ((float) смещение)/((float) filelength); SetProgress ((int) recep); Offset += numReadBytes; } System.out.println ("numReadBytes =" + numReadBytes); if (offset <fileLength) {numReadBytes = input.read (content); System.out.println ("numReadBytes =" + numReadBytes); System.out.println ("Ошибка содержимого файла на стороне сервера"); } else {System.out.println ("Задача приема файла выполнила правильно"); } setProgress (100); // Скажите клиенту закрыть сокет сейчас, мы уже успешно получаем файл !! BufferedWriter BufferedWriter = New BufferedWriter (New OutputStreamWriter (_msocket.getOutputStream ())); BufferedWriter.Write ("DOD/R/N"); BufferedWriter.flush (); // Закройте файл и выход output.close (); _msocket.close (); возврат 100; }} Клиент:
FileTransferClient - это класс пользовательского интерфейса клиента, который реализует соединение с сервером, а затем выбирает
Файлы, которые должны быть переданы (изображения, PDFS, Word Documents и т. Д.). Если не
Введите информацию о сервере, и появится подсказка. Порт был указан как: 9999
Кнопка [Отправить файл] откроет поле выбора файла. После того, как пользователь выбирает файл для передачи, создайте
FileTransfertask Thread и начните выполнять передачу файла. Код пользовательского интерфейса клиента выглядит следующим образом:
пакет com.gloomyfish.socket.tutorial.fileTransfer; импортировать java.awt.borderlayout; импортировать java.awt.flowlayout; импортировать java.awt.gridlayout; импортировать java.awt.event.actionevent; импортировать java.awt.event.actionlistener; Импорт java.beans.propertychangeevent; Импорт java.beans.propertychangelistener; Импорт java.io.file; Импорт java.net.inetsocketAddress; Импорт java.net.socketAddress; импортировать javax.swing.borderfactory; импортировать javax.swing.boxlayout; Импорт javax.swing.jbutton; Импорт javax.swing.jfilechooser; импортировать javax.swing.jframe; импортировать javax.swing.jlabel; импортировать javax.swing.joptionpane; импортировать javax.swing.jpanel; Импорт javax.swing.jprogressbar; импортировать javax.swing.jtextfield; /*** Я обычно пишу комментарии на английском языке, и иногда я также пишу китайские комментарии, но я думаю, что написание английского* комментариев более объединено с кодом и ничего больше. */ public class fileTransferClient Extens JFrame реализует ActionListener {/ ** * */ Private Static Long Long Serialversionuid = 1L; публичная окончательная статическая строка send_cmd = "Отправить файл"; Public Final Static int minimum = 0; Public Final Static Int Maximum = 100; // public final Static String connect_cmd = "connect"; Частный JButton SendFileBtn; Private Jtextfield Serverfield; Частный JTextfield Portfield; Частный бар JProgressbar; public fileTransferClient () {super ("File Transfer Client"); initComponents (); } private void initComponents () {getContentPane (). setlayout (new Borderlayout ()); JPanel ProgressPanel = new jPanel (); ProgressPanel.SetLayout (New BoxLayout (ProgressPanel, Boxlayout.y_axis); Bar = new jprogressbar (); ProgressPanel.Add (bar); bar.setminimum (минимум); bar.setMaximum (максимум); JPanel SeragesttingPanel = new jpanel (); serversettypletpepaypepletpepletpepletpepletpepletylep Gridlayout (2,2,5,5); ServersettingPanel.Add (New Jlabel («Серверный порт:»); BtnPanel.Add (SendFileBtn); @Override public actionperformed (actionevent e) {string command = e.getActionCommand (); Status = chooser.showopendialog (null); task.addpropertychangelistener (new PropertyChangelistener () {public void PropertyChange (PropertyChangeEvent evt) {if ("Прогресс" .Equals (evt.getPropertyName ())) {bar.SetValue (((Integer) evt.getNewValue (); } else {// Сделать ничего}} public void showeccess () {bar.setValue (100); / ** Убедитесь, что пользовательский интерфейс уже имеет некоторую правильную информацию о вводе !!! Integer.parseint (port); client.setsize (400, 400); Основными функциями, реализованными FileTransfertask:
Полный исходный код этого класса заключается в следующем:
пакет com.gloomyfish.socket.tutorial.fileTransfer; Импорт java.io.bufferedinputstream; Импорт java.io.bufferedReader; импортировать java.io.datainputstream; импортировать java.io.dataoutputstream; Импорт java.io.file; импортировать java.io.fileinputstream; импортировать java.io.ioexception; Импорт java.io.inputStreamReader; импортировать java.net.socket; Импорт java.net.socketAddress; импортировать javax.swing.swingworker; открытый класс FileTransfertask Extends SwingWorker <Integer, Object> {Private File SelectedFile; Частный сокет MSCOCKET; Частный адрес сокетаддресса; Частный родитель FileTransferClient; public filetransfertask (файл файла, адрес SocketAddress, владелец FileTransferClient /*, jProgressbar Progress* /) {this.address = Address; this.selectedFile = file; msocket = new Socket (); this.parent = владелец; } @Override Protected integer doInbackground () бросает исключение {// Получить размер длины длиной файла = selectedFile.length (); if (length> integer.max_value) {бросить новое ioexception («не может полностью прочитать файл» + selectedFile.getName () + «как это слишком длинное (" + длина + "байты, макс поддерживает" + integer.max_value + ")"); } msocket.connect (адрес); // Создать байтовый массив для хранения данных файла msocket.setsolinger (true, 60); DateOutputStream Dout = new DataOutputStream (msocket.getOutputStream ()); // Теперь мы начинаем отправлять мета -информацию файла. dout.writeutf (selectedFile.getName ()); dout.writelong (длина); dout.flush (); // Конечный комментарий filedatapackage pdata = new filedatapackage (); DataInputStream is = new DataInputStream (new FileInputStream (selectedFile)); байт [] байты = новый байт [2048]; // Читать в байтах int offset = 0; int numRead = 0; int fsize = (int) длина; while (offset <fsize && (numread = is.read (bytes, 0, bytes.length))> = 0) {pdata.setData (bytes, numread); dout.write (pdata.getpackagedata (), 0, pdata.getpackagedata (). Length); dout.flush (); offset += numread; float precent = 100.0f * ((float) смещение)/((float) fsize); SetProgress ((int) recep); } System.out.println ("Total Send Bytes =" + Offset); // Убедитесь, что все байты были прочитаны в if (offset <fsize) {бросить новое ioException («не может полностью перенести файл» + selectedFile.getName ()); } msocket.shutdownOutput (); // получение сообщения о передаче файла успешно от подключения BufferedInputStream StreamReader = new BufferedInputStream (msocket.getInputStream ()); BufferedReader BufferedReader = new BufferedReader (New InputStreamReader (StreamReader)); String donemsg = bufferedReader.readline (); if ("end" .equals (donemsg)) {parent.showsuccess (); } // Закройте входной поток ввода файла SetProgress (100); // dout.close (); msocket.close (); is.close (); System.out.println ("закройте сейчас ..."); возврат 100; }}Класс пакетов выглядит следующим образом, не объясняется!
пакет com.gloomyfish.socket.tutorial.fileTransfer; / ** * Это очень простой протокол передачи файлов через TCP Socket */ public Class filedatapackage {private int dataLength; // длина данных в пакете, два байта частных байтовых байт [] Databuff; // Максимальные данные в пакете, Meici не должен превышать 2048 байт общедоступного окончательного статического байта [] eof = new Byte [] {'e', 'o', 'f'}; public fileDatApackage () {dataLength = 0; Databuff = новый байт [2048]; } public byte [] getPackagedata () {byte [] pdata = new Byte [dataLength]; // end Comment System.ArrayCopy (Databuff, 0, PDATA, 0, DataLength); вернуть Pdata; } public void setData (byte [] data, int bsize) {dataLength = bsize; for (int i = 0; i <databuff.length; i ++) {if (i <bsize) {databuff [i] = data [i]; } else {databuff [i] = ''; }}}}Максимальное количество байтов, отправленных за время, составляет 2048 байт. Окончательный эффект работы программы заключается в следующем (Win7 + JDK6U30):
Выше приведено в этой статье, я надеюсь, что это будет полезно для каждого обучения.