Java socket传输

    这是我的第一个任务,编写一个应用Java socket进行文件传输的小程序。

    根据要求,我编成了一个FTP,还是很不完善,比如跨网络传输时丢包情况相当严重。

这是服务器程序:

import javax.swing.filechooser.FileFilter;
import javax.swing.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class RemoteFileServer extends JFrame {
  private int listenPort = 3000, file_port = 3001;
  private JButton path_bt, start_bt, stop_bt;
  private JTextField path_field, port_field;
  private JLabel path_label, port_label, label;
  private boolean flag = true; //标记服务是否启动
  private ServerSocket server, file_server;
  private Socket incomingConnection = null, file_conn;

  public RemoteFileServer() {

  JFrame frame = new JFrame();
  JPanel panel = new JPanel(); //主要是用它的流布局
  frame.setSize(290, 140);
  path_bt = new JButton("选择文件夹"); //选择作为根路径的文件夹,即此文件夹内的文件,能够在客户端列出。
  label = new JLabel("服务已停止");
  path_label = new JLabel("路径");
  port_label = new JLabel("端口");
  path_field = new JTextField(20);
  path_field.setEditable(false);
  port_field = new JTextField(20);
  start_bt = new JButton("启动服务");
  stop_bt = new JButton("停止服务");

  //给按钮添加事件,选择客户端可下载的文件所在的文件夹
  path_bt.addActionListener(new ActionListener() {
  public void actionPerformed(ActionEvent e) {
  JFileChooser chooser = new JFileChooser();
  chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
  int value = chooser.showOpenDialog(null);
  if (value == JFileChooser.APPROVE_OPTION) {
  path_field.setText(chooser.getSelectedFile().getPath());
  }
  }
  });

  //启动服务
  start_bt.addActionListener(new ActionListener() {
  public void actionPerformed(ActionEvent e) {
  flag = true;
  if (!port_field.getText().trim().equals("")) {
  listenPort = Integer.parseInt(port_field.getText().trim());
  }
  //启动服务的核心代码
  acceptConnections(listenPort);
  //提示,服务启动了
  label.setText("服务已启动");
  }
  });
  //停止服务
  stop_bt.addActionListener(new ActionListener() {
  public void actionPerformed(ActionEvent e) {
  flag = false;
  label.setText("服务已停止");
  }
  });

  panel.add(path_label);
  panel.add(path_field);
  panel.add(port_label);
  panel.add(port_field);
  panel.add(path_bt);
  panel.add(start_bt);
  panel.add(stop_bt);
  panel.add(label);
  frame.add(panel);
  frame.setResizable(false);
  frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  frame.setVisible(true);
  }

  private class ConnThread extends Thread {
  public void run() {
  while (flag) {
  try {
  incomingConnection = server.accept();
  putFileList(incomingConnection);
  } catch (IOException e) {
  e.printStackTrace();
  }
  }
  }
  }


  private class FileThread extends Thread {
  public void run() {
  while (flag) {
  try {
  file_conn = file_server.accept();
  //这里又启动一个线程,等待客户端获取文件
  new SendThread().start();
  } catch (IOException e) {
  e.printStackTrace();
  }
  }
  }
  }

  //线程类,等待客户机下载文件
  private class SendThread extends Thread {
  public void run() {
  handleConnection(file_conn);
  }
  }

  public void acceptConnections(int port) {
  //创建ServerSocket
  try {
  if (server == null) {
  server = new ServerSocket(port);
  }
  if (file_server == null) {
  file_server = new ServerSocket(file_port);
  }
  //启动了一个线程,来等待客户端的链接,这样主程序才不会阻塞
  new ConnThread().start();
  new FileThread().start();
  } catch (IOException e) {
  e.printStackTrace();
  }

  }

  //这是把文件夹里的文件列表传给客户端
  //方法是,将所有的文件名组成一个字符串,之间以分号隔开,到客户端去解析
  private void putFileList(Socket incomingConnection) {
  //获得客户端流,将文件写到这个流里面去
  OutputStream outputToSocket = null;
  try {
  outputToSocket = incomingConnection.getOutputStream();
  } catch (IOException e) {
  e.printStackTrace();
  }

  DataOutputStream out = new DataOutputStream(outputToSocket);

  File file = new File(path_field.getText());
  String[] file_names = file.list();
  String s = "";
  for (String str : file_names) {
  s = s + str + ";";
  }
  try {
  out.writeUTF(s);
  out.flush();
  } catch (IOException e) {
  e.printStackTrace();
  }
  }


  //这是传送文件的核心代码,如果接受到客户端的消息以"#"a开头,那么解析出"#"后的文件名,并创建流给与下载
  public void handleConnection(Socket conn) {
  try {
  //获得客户端流,将文件写到这个流里面去
  OutputStream outputToSocket = conn.getOutputStream();

  //获得客户端的输入流
  InputStream client_input = conn.getInputStream();
  //封装客户流
  DataInputStream cleint_reader = new DataInputStream(client_input);

  String str = cleint_reader.readUTF().trim();
  System.out.println(str);
  if (str.startsWith("#")) {
  String file_str = str.substring(1, str.length());
  System.out.println(file_str);
  File file = new File(path_field.getText(), file_str);
  FileInputStream filein = new FileInputStream(file);

  byte[] b = new byte[1024];
  int i = 0;

  while (filein.read(b) != -1) {
  outputToSocket.write(b);
  }
  outputToSocket.flush();
  outputToSocket.close();
  cleint_reader.close();
  filein.close();
  System.out.println("传输完毕");
  }
  } catch (Exception e) {
  System.out.println("Error handling a client: " + e);
  }
  }

  public static void main(String[] args) {
  RemoteFileServer server = new RemoteFileServer();
  }

}

*************************************分隔符**********************************

下面是客户端,本机调试IP:127.0.0.1,Port:3000

import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.*;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.table.DefaultTableModel;
import java.io.*;
import java.net.*;
import java.util.Vector;
public class RemoteFileClient extends JFrame {
 private JTextField tfip, tfport;
  private String hostIP;
 private JLabel tfip_label,port_label;
 private int hostPort, filePort = 3001;
 private Socket client;
 private JButton connect_bt;
 private String selected;
 public RemoteFileClient(String aHostIp, int aHostPort) {
  hostIP = aHostIp;
  hostPort = aHostPort;
 }

 public RemoteFileClient() {
  super("客户端");
  setSize(350, 200);
  setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  JPanel panel = new JPanel();
  JFrame frame = new JFrame();
  tfip_label = new JLabel("IP");
  port_label = new JLabel("端口");
  tfip = new JTextField(20);
  tfport = new JTextField(20);
  connect_bt = new JButton("连接");
  // 连接添加事件,读取服务器的文件列表
  connect_bt.addActionListener(new ActionListener() {
  public void actionPerformed(ActionEvent e) {
  String ip = tfip.getText();// 取得IP
  int port = Integer.parseInt(tfport.getText());
  initClient(ip, port);
  setUpConnect();// 连接到服务器端

  }

  });

 
   
  panel.add(tfip_label); 
  panel.add(tfip); 
  panel.add(port_label); 
  panel.add(tfport);  
  panel.add(connect_bt); 
  frame.add(panel);  
  frame.setResizable(false); 
  frame.setSize(270,120);  
  frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
  frame.setVisible(true); 
  }
 
 public void initClient(String aHostIp, int aHostPort) {
  hostIP = aHostIp;
  hostPort = aHostPort;
 }

 public void setUpConnect() {
  try {
  client = new Socket(hostIP, hostPort);
  // 创建客户端的Socket,连接到Server上
  DataInputStream in = new DataInputStream(client.getInputStream());
  // 从socket获得流
  String files = "";
  files = in.readUTF(); 
  // 取得从服务器取得的文件列表字符串
  if (!files.trim().equals("")) {
  showFileList(files);
  }  
 in.close();  
} catch (UnknownHostException e) { 
  System.out.println("Error setting up connection:unknow host at"
  + hostIP + ":" + hostPort);
  } catch (IOException e) {
  System.out.println("Error setting up socket connection:" + e);
  }
 }
 // 创建一个文件列表窗口
 private void showFileList(String files) {
  JFrame frame = new JFrame();
  frame.setSize(400, 400);
  JTable table = new JTable();
  createTable(table, files);
  JScrollPane pane = new JScrollPane(table);
  frame.add(pane);
  JButton get_file = new JButton("传输文件");
  // 获取文件
  get_file.addActionListener(new ActionListener() {
  public void actionPerformed(ActionEvent e) {
  new DownFile().start();// 启动一个下载线程,以免阻塞主线程
  }
  });
  frame.add(get_file, BorderLayout.SOUTH);
  frame.setVisible(true);
 }
 public class DownFile extends Thread {
  public void run() {
  JFileChooser chooser = new JFileChooser();
  chooser.setSelectedFile(new File(".", selected));
  // 设置默认保存的文件名
  int value = chooser.showSaveDialog(null);
  if (value == JFileChooser.APPROVE_OPTION) {
  try {
  client = new Socket(hostIP, filePort);
// 这里首先给服务器一个消息,消息以"#"开头加上文件名,以告诉服务器下载的文件是什么
  DataOutputStream out = new DataOutputStream(client
  .getOutputStream());
  out.writeUTF("#" + selected);
  out.flush();
  // 取得选取的文件
  File file = chooser.getSelectedFile();
  // 准备写入
  FileOutputStream fileout = new FileOutputStream(file); 
  // 取得服务器的流 
  InputStream in = client.getInputStream(); 
  // 传输过程 
  byte[] b = new byte[1024]; 
  int i = 0;  
  while (in.read(b) != -1) { 
  fileout.write(b);
  } 
  fileout.flush();
  // 关闭流
  fileout.close();
  out.close(); 
  in.close();  
  } catch (IOException e1) { 
  e1.printStackTrace(); 
  }  
 }
  }
 }
 // 创建文件列表的,参考Table的API
 private void createTable(JTable table, String files) { 
 DefaultTableModel tableModel = new DefaultTableModel();
  final Vector row = new Vector();
  Vector cell; 
 String[] f = files.split(";"); 
 for (String str : f) {  
 cell = new Vector();  
 cell.add(str);  
 row.add(cell); 
 } 
 Vector head = new Vector(); 
 head.add("文件"); 
 tableModel.setDataVector(row, head);
 table.setModel(tableModel); 
 ListSelectionModel model = table.getSelectionModel();
  model.addListSelectionListener(new ListSelectionListener() { 
  public void valueChanged(ListSelectionEvent e) { 
  if (e.getValueIsAdjusting()) {  
  int index = ((DefaultListSelectionModel) (e.getSource()))
  .getAnchorSelectionIndex(); 
  selected = (String) ((Vector) row.get(index)).get(0); 
  System.out.println(selected);  
  }  
 }  
});
 }
 public static void main(String[] argumnets) { 
 RemoteFileClient frame = new RemoteFileClient();
 }
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值