国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務器之家 - 編程語言 - JAVA教程 - Java基于TCP方式的二進制文件傳輸

Java基于TCP方式的二進制文件傳輸

2020-03-22 13:07gloomyfish JAVA教程

這篇文章主要為大家介紹了Java基于TCP方式的二進制文件傳輸,一個基于Java Socket協議之上文件傳輸的完整示例,基于TCP通信完成,感興趣的小伙伴們可以參考一下

一個基于Java Socket協議之上文件傳輸的完整示例,基于TCP通信完成。

除了基于TCP的二進制文件傳輸,還演示了JAVA Swing的一些編程技巧,Demo程序

實現主要功能有以下幾點:

  • 1.基于Java Socket的二進制文件傳輸(包括圖片,二進制文件,各種文檔work,PDF)
  • 2.SwingWorker集合JProgressBar顯示實時傳輸/接受完成的百分比
  • 3.其它一些Swing多線程編程技巧

首先來看一下整個Dome的Class之間的關系圖:

Java基于TCP方式的二進制文件傳輸

下面按照上圖來詳細解釋各個類的功能與代碼實現:

服務器端:

FileTransferServer類的功能首先是在端口9999創建一個服務器套接字并

開始監聽連接。相關代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
private void startServer(int port) {
 try {
  serverSocket = new ServerSocket(port);
  System.out.println("Server started at port :" + port);
  while(true) {
   Socket client = serverSocket.accept(); // blocked & waiting for income socket
   System.out.println("Just connected to " + client.getRemoteSocketAddress());
   FileReceiveTask task = new FileReceiveTask(client);
   bar.setValue(0); // reset it now
   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提供了一個非常有力的工具類來
監控任意Bean Model的數據改變,程序通過添加該監聽器實現對

SwingWorker的progress屬性值改變的事件捕獲,然后更新JProgressBar

實例對象,實現了UI的刷新。FileTransferServer類的完整源代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package com.gloomyfish.socket.tutorial.filetransfer;
 
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
 
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
 
public class FileTransferServer extends JFrame implements ActionListener {
 /**
  *
  */
 public final static String START_SVR = "Start";
 public final static String SHUT_DOWN_SVR = "Shut Down";
 public final static String END_FLAG = "EOF";
 private static final long serialVersionUID = 1L;
 private ServerSocket serverSocket;
 private JButton startBtn;
 private JProgressBar bar;
 public FileTransferServer() {
  super("File Server");
  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(bar);
  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 startServer(int port) {
  try {
   serverSocket = new ServerSocket(port);
   System.out.println("Server started at port :" + port);
   while(true) {
    Socket client = serverSocket.accept(); // blocked & waiting for income socket
    System.out.println("Just connected to " + client.getRemoteSocketAddress());
    FileReceiveTask task = new FileReceiveTask(client);
    bar.setValue(0); // reset it now
    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 showSuccess() {
  bar.setValue(100);
  JOptionPane.showMessageDialog(this, "file received successfully!");
 }
 
 @Override
 public void actionPerformed(ActionEvent e) {
  if(START_SVR.equals(e.getActionCommand())) {
   Thread startThread = new Thread(new Runnable() {
    public void run() {
     startServer(9999);
    }
   });
   startThread.start();
   startBtn.setEnabled(false);
  } else if(SHUT_DOWN_SVR.equals(e.getActionCommand())) {
 
  } else {
   // do nothing...
  }
 }
  
 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);
 }
}

FileReceiveTask是服務器端的文件接受類:
首先從建立的TCP流中得到文件名與文件大小,然后開始接受文件內容字節

并寫入創建的文件對象流中,最后驗證文件大小與寫入的字節流是否相等

最后發送一條消息到文件發送方,告訴對方文件傳輸完成,可以關閉TCP流。

該類的完整源代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
package com.gloomyfish.socket.tutorial.filetransfer;
 
import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
 
import javax.swing.SwingWorker;
 
public class FileReceiveTask extends SwingWorker<Integer, Object> {
 private Socket _mSocket;
 public FileReceiveTask(Socket client) {
  this._mSocket = client;
 }
 
 @Override
 protected Integer doInBackground() throws Exception {
  // get file meta information
  DataInputStream input = new DataInputStream(_mSocket.getInputStream());
  String fileName = input.readUTF();
  int fileLength = (int)input.readLong(); // number of total bytes
  File file = new File("C:\\Users\\fish\\Downloads" + File.separator + fileName);
  BufferedOutputStream output = new BufferedOutputStream(new FileOutputStream(file));
  System.out.println("Received File Name = " + fileName);
  System.out.println("Received File size = " + fileLength/1024 + "KB");
   
  // start to receive the content of the file and write them
  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)offset)/((float)fileLength);
   setProgress((int)precent);
   offset += numReadBytes;
  }
  System.out.println("numReadBytes = " + numReadBytes);
  if(offset < fileLength) {
   numReadBytes = input.read(content);
   System.out.println("numReadBytes = " + numReadBytes);
   System.out.println("File content error at server side");
  } else {
   System.out.println("File Receive Task has done correctly");
  }
  setProgress(100);
   
  // tell client to close the socket now, we already receive the file successfully!!
  BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(_mSocket.getOutputStream()));
  bufferedWriter.write("DONE\r\n");
  bufferedWriter.flush();
   
  // close the file and socket
  output.close();
  _mSocket.close();
  return 100;
 }
 
}

客戶端:
FileTransferClient是客戶端UI類,用來實現到服務端的連接,然后選擇

要傳輸的文件(圖片,PDF,Word文檔等各種二進制文件)。如果沒有

輸入服務器信息,會彈出提示要求輸入。端口已經指定為:9999

【send File】按鈕會打開文件選擇框,用戶選擇要傳輸文件以后,創建

FileTransferTask線程,并開始執行文件傳送。客戶端UI代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package com.gloomyfish.socket.tutorial.filetransfer;
 
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
 
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JTextField;
/**
 * 我一般寫英文注釋,偶爾我也會寫中文注釋,只是覺得寫英文
 * 注釋跟代碼比較統一,無他。
 */
public class FileTransferClient extends JFrame implements ActionListener {
 /**
  *
  */
 private static final long serialVersionUID = 1L;
 public final static String SEND_CMD = "Send File";
 public final static int MINIMUM = 0;
 public final static int MAXIMUM = 100;
 // public final static String CONNECT_CMD = "Connect";
 private JButton sendFileBtn;
 private JTextField serverField;
 private JTextField portField;
 private JProgressBar bar;
  
 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(MINIMUM);
  bar.setMaximum(MAXIMUM);
  JPanel serverSettingPanel = new JPanel();
  serverSettingPanel.setLayout(new GridLayout(2,2,5,5));
  serverSettingPanel.setBorder(BorderFactory.createTitledBorder("Server Setting"));
  serverField = new JTextField();
  portField = new JTextField();
  serverSettingPanel.add(new JLabel("Server IP/Host:"));
  serverSettingPanel.add(serverField);
  serverSettingPanel.add(new JLabel("Server Port:"));
  serverSettingPanel.add(portField);
   
  sendFileBtn = new JButton(SEND_CMD);
  JPanel btnPanel = new JPanel();
  btnPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
  btnPanel.add(sendFileBtn);
  getContentPane().add(serverSettingPanel, BorderLayout.NORTH);
  getContentPane().add(btnPanel, BorderLayout.SOUTH);
  getContentPane().add(progressPanel, BorderLayout.CENTER);
  sendFileBtn.addActionListener(this);
 }
 
 @Override
 public void actionPerformed(ActionEvent e) {
  String command = e.getActionCommand();
  if(command.equals(SEND_CMD)) {
   if(checkNull()) {
    JOptionPane.showMessageDialog(this, "Please enter server host and port in order to set up the connection!");
    return;
   }
   JFileChooser chooser = new JFileChooser();
   int status = chooser.showOpenDialog(null);
   if (status == JFileChooser.APPROVE_OPTION) {
    File f = chooser.getSelectedFile();
    SocketAddress address = new InetSocketAddress(getServer(), getPort());
    FileTransferTask task = new FileTransferTask(f, address, this);
    bar.setValue(0);
    task.addPropertyChangeListener(new PropertyChangeListener() {
     public void propertyChange(PropertyChangeEvent evt) {
      if ("progress".equals(evt.getPropertyName())) {
       bar.setValue((Integer) evt.getNewValue());
      }
     }
    });
    task.execute(); // 異步task執行
   }
  } else {
   // do nothing
  }
 }
  
 public void showSuccess() {
  bar.setValue(100);
  JOptionPane.showMessageDialog(this, "file send successfully!");
 }
  
 public String getServer() {
  return serverField.getText().trim();
 }
  
 public int getPort() {
  return Integer.parseInt(portField.getText().trim());
 }
 /**
  * make sure the UI already have some correct input information here!!!
  * @return
  */
 private boolean checkNull() {
  String serverName = serverField.getText();
  String port = portField.getText();
  if(serverName == null || serverName.length() == 0 || port == null || port.length() == 0) {
   return true;
  }
   
  try {
   Integer.parseInt(port); // try to parse it as server port number , validation code.
  } catch(NumberFormatException ne) {
   ne.printStackTrace();
   return true;
  }
  return false;
 }
  
 public static void main(String[] args) {
  FileTransferClient client = new FileTransferClient();
  client.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  client.setSize(400, 400);
  client.setResizable(false);
  // client.pack();
  client.setVisible(true);
 }
 
}

FileTransferTask實現的功能主要有:

  • 1. 發送文件meta信息到接受方(文件名與文件大小)
  • 2. 讀取文件內容字節寫入Socket字節流中,發送到接受方
  • 3. 從Socket字節流中讀取對方接受完成通知信息,調用彈出文件傳輸成功信息

該類完全源代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
package com.gloomyfish.socket.tutorial.filetransfer;
 
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.SocketAddress;
 
import javax.swing.SwingWorker;
 
public class FileTransferTask extends SwingWorker<Integer, Object> {
 private File selectedFile;
 private Socket mSocket;
 private SocketAddress address;
 private FileTransferClient parent;
  
 public FileTransferTask(File file, SocketAddress address, FileTransferClient owner /*, JProgressBar progress*/) {
  this.address = address;
  this.selectedFile = file;
  mSocket = new Socket();
  this.parent = owner;
 }
  
 @Override
 protected Integer doInBackground() throws Exception {
  // Get the size of the file
  long length = selectedFile.length();
  if (length > Integer.MAX_VALUE) {
   throw new IOException("Could not completely read file " + selectedFile.getName() + " as it is too long (" + length + " bytes, max supported " + Integer.MAX_VALUE + ")");
  }
   
  mSocket.connect(address);
   
  // Create the byte array to hold the file data
  mSocket.setSoLinger(true, 60);
  DataOutputStream dout = new DataOutputStream(mSocket.getOutputStream());
  // now we start to send the file meta info.
  dout.writeUTF(selectedFile.getName());
  dout.writeLong(length);
  dout.flush();
  // end comment
  FileDataPackage pData = new FileDataPackage();
  DataInputStream is = new DataInputStream(new FileInputStream(selectedFile));
  byte[] bytes = new byte[2048];
 
  // Read in the bytes
  int offset = 0;
  int numRead = 0;
  int fsize = (int)length;
  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)offset)/((float)fsize);
   setProgress((int)precent);
  }
  System.out.println("total send bytes = " + offset);
  // Ensure all the bytes have been read in
  if (offset < fsize) {
   throw new IOException("Could not completely transfer file " + selectedFile.getName());
  }
  mSocket.shutdownOutput();
   
  // receive the file transfer successfully message from connection
   
  BufferedInputStream streamReader = new BufferedInputStream(mSocket.getInputStream());
  BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(streamReader));
  String doneMsg = bufferedReader.readLine();
  if("DONE".equals(doneMsg)) {
   parent.showSuccess();
  }
  // Close the file input stream
  setProgress(100);
  // dout.close();
  mSocket.close();
  is.close();
  System.out.println("close it now......");
  return 100;
 }
}

數據包類如下,不解釋!

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package com.gloomyfish.socket.tutorial.filetransfer;
/**
 * this is very simple file transfer protocol over TCP socket
 */
public class FileDataPackage {
 
 private int dataLength; // 數據包中數據長度,兩個字節
 private byte[] databuff; // 數據包中數據,meici最大不超過2048字節
  
 public final static byte[] EOF = new byte[]{'E', 'O','F'};
  
 public FileDataPackage() {
  dataLength = 0;
  databuff = new byte[2048];
 }
  
 public byte[] getPackageData() {
  byte[] pData = new byte[dataLength];
  // end comment
  System.arraycopy(databuff, 0, pData, 0, dataLength);
  return 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):

Java基于TCP方式的二進制文件傳輸

Java基于TCP方式的二進制文件傳輸

以上就是本文的全部內容,希望對大家的學習有所幫助。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 久久久久国产一级毛片高清片 | 国产精品美乳一区二区免费 | 中文字幕视频一区 | 欧美成人免费看 | 一区二区三区四区国产 | 国产欧美精品一区二区三区 | 不卡一区在线观看 | 日韩在线播放一区二区 | 久久久久黑人 | 日韩中文视频 | 欧美一区二区精品 | 综合在线视频 | 免费午夜视频 | 成人影音 | 中文字幕国产在线视频 | 久草 在线 | 日日夜夜精品视频 | 欧美成人免费在线 | 免费视频成人国产精品网站 | 成人精品国产免费网站 | 黄色av大片| 在线观看免费毛片视频 | 精品久久av | 欧美污污 | 日本一区二区三区精品视频 | 国产日韩欧美一区二区 | 在线免费观看视频 | 久久av一区二区三区 | 久久久免费少妇高潮毛片 | 亚洲欧美日韩另类一区二区 | 日韩城人网站 | 国产精品18久久久久久久久久久久 | 天天天操 | 日本久久网 | 自拍偷拍 亚洲 | 精品自拍视频在线观看 | 一级黄色免费网站 | 不卡av电影在线观看 | 日本在线黄色 | 久久中文字幕一区 | 精品av|