Java写的小聊天软件


最近我刚刚学习了Java 学的还不是很精通,但是总想写点什么 就写了个聊天软件。

采用的是C/S模式。

目前的问题是,只能一对一的聊天,虽然采用了服务器 客户端,但是连接多个的时候会出现问题。

除了聊天之外,还写了个文件传送的类,经过测试可以传送文件,但是不能续传,文件校验也没有做,文件传输速度也没有做。

发上来的目的就是和大家交流一下经验,嘿嘿

下面这个文件是用来连接服务器的,并且打开主程序




package chatv3.test1.mainapp;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;

public class ClientConnect {
	JFrame frameConnect = new JFrame("客户端连接");
	private JTextField textField_Ip;
	private JTextField textField_Port;
	private JButton btnConnect;
	private String serverIP = null;
	private int port = 8888;
	private Socket socketChat = null;

	public ClientConnect() {
		frameConnect.setResizable(false);
		frameConnect.setVisible(true);
		frameConnect.setBounds(800, 300, 365, 145);
		frameConnect.getContentPane().setLayout(null);

		JLabel lblServerIp = new JLabel("服务器IP");
		lblServerIp.setBounds(10, 22, 70, 15);
		frameConnect.getContentPane().add(lblServerIp);

		JLabel lblServerPort = new JLabel("服务器端口");
		lblServerPort.setBounds(10, 62, 70, 15);
		frameConnect.getContentPane().add(lblServerPort);

		textField_Ip = new JTextField("127.0.0.1");
		textField_Ip.setBounds(98, 18, 87, 21);
		frameConnect.getContentPane().add(textField_Ip);
		textField_Ip.setColumns(10);

		textField_Port = new JTextField("8888");
		textField_Port.setBounds(98, 58, 89, 21);
		frameConnect.getContentPane().add(textField_Port);
		textField_Port.setColumns(10);

		btnConnect = new JButton("连接服务器");
		btnConnect.setBounds(221, 58, 110, 23);
		frameConnect.getContentPane().add(btnConnect);

		frameConnect.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frameConnect.validate();
		addListener();
	}

	public static void main(String[] args) {
		new ClientConnect();
	}

	/*
	 * 连接主机,给文本域Port和连接按钮btnConnect均添加监听
	 */
	private void addListener() {
		textField_Port.addActionListener(new ClientListener());
		btnConnect.addActionListener(new ClientListener());
	}

	/*
	 * 处理监听 实现连接服务器
	 */
	class ClientListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent arg0) {
			new ClientSocketThread().start();
		}

	}

	class ClientSocketThread extends Thread {

		@Override
		public void run() {

			try {
				serverIP = textField_Ip.getText().toString();
				port = Integer.parseInt(textField_Port.getText());
				socketChat = new Socket(serverIP, port);
				if (socketChat != null) {
					JOptionPane.showMessageDialog(frameConnect, "已连接主机"
							+ serverIP + ":" + port);
					new ClientMainFrame(socketChat, serverIP);
					frameConnect.dispose();
				}
			} catch (UnknownHostException e) {
				JOptionPane.showMessageDialog(frameConnect, "无法连接主机");
				e.printStackTrace();
			} catch (IOException e) {
				JOptionPane.showMessageDialog(frameConnect, "无法连接主机");
				e.printStackTrace();
			} catch (NumberFormatException e) {
				JOptionPane.showMessageDialog(frameConnect, "请输入数字");
				e.printStackTrace();
			}
		}
	}
}

下面是客户端的主程序



package chatv3.test1.mainapp;

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.border.TitledBorder;

public class ClientMainFrame {
	JFrame frameMain = new JFrame("客户端");
	private JTextField textField_SendMessage;
	private JTextArea textArea_out;
	private JButton btnSendFile;
	private Socket socketChat = null;
	private DataInputStream dataInputStream = null;
	private DataOutputStream dataOutputStream = null;
	private JButton btnSendMessage;
	private String ipString = null;
	private int port = 8887;
	private long fileLength;
	private String fileName = null;

	public ClientMainFrame(Socket socketChat, String ipString) {
		this.socketChat = socketChat;
		this.ipString = ipString;
		new ClientThread().start();
		frameMain.getContentPane().setLayout(null);
		frameMain.setBounds(500, 300, 589, 343);

		JPanel panel_left = new JPanel();
		panel_left.setBorder(new TitledBorder(null, "聊天区",
				TitledBorder.LEADING, TitledBorder.TOP, null, null));
		panel_left.setBounds(10, 10, 310, 288);
		frameMain.getContentPane().add(panel_left);
		panel_left.setLayout(null);

		JScrollPane scrollPane = new JScrollPane();
		scrollPane.setBounds(10, 22, 281, 215);
		panel_left.add(scrollPane);

		textArea_out = new JTextArea();
		textArea_out.setEditable(false);
		scrollPane.setViewportView(textArea_out);

		textField_SendMessage = new JTextField();
		textField_SendMessage.setBounds(10, 245, 178, 21);
		panel_left.add(textField_SendMessage);
		textField_SendMessage.setColumns(10);

		btnSendMessage = new JButton("发送");
		btnSendMessage.setBounds(198, 244, 93, 23);
		panel_left.add(btnSendMessage);

		JPanel panel = new JPanel();
		panel.setBorder(new TitledBorder(null, "功能区", TitledBorder.LEADING,
				TitledBorder.TOP, null, null));
		panel.setBounds(330, 10, 241, 288);
		frameMain.getContentPane().add(panel);
		panel.setLayout(null);

		JPanel panel_1 = new JPanel();
		panel_1.setBounds(10, 30, 219, 128);
		panel.add(panel_1);
		GridBagLayout gbl_panel_1 = new GridBagLayout();
		gbl_panel_1.columnWidths = new int[] { 0, 0 };
		gbl_panel_1.rowHeights = new int[] { 0, 0 };
		gbl_panel_1.columnWeights = new double[] { 0.0, Double.MIN_VALUE };
		gbl_panel_1.rowWeights = new double[] { 0.0, Double.MIN_VALUE };
		panel_1.setLayout(gbl_panel_1);

		btnSendFile = new JButton("发送文件");
		GridBagConstraints gbc_btnSendFile = new GridBagConstraints();
		gbc_btnSendFile.gridx = 0;
		gbc_btnSendFile.gridy = 0;
		panel_1.add(btnSendFile, gbc_btnSendFile);
		addListener();
		frameMain.setVisible(true);
		frameMain.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

	}

	private void initStream() throws IOException {

		dataInputStream = new DataInputStream(socketChat.getInputStream());
		dataOutputStream = new DataOutputStream(socketChat.getOutputStream());
	}

	private void addListener() {
		btnSendMessage.addActionListener(new SendMessage());
		btnSendFile.addActionListener(new SendFile());
		textField_SendMessage.addActionListener(new SendMessage());
	}

	private void sendFile() throws IOException {
		FileSend fileSend = new FileSend(ipString, port);
		fileLength = fileSend.getFileLength();
		fileName = fileSend.getFileName();
	}

	class SendFile implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent e) {
			try {
				sendFile();
			} catch (IOException e1) {
				e1.printStackTrace();
			}
		}

	}

	class SendMessage implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent arg0) {
			try {
				sendMessage();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		// 发送内容为空 不进行判断bug
		private void sendMessage() throws IOException {
			if (socketChat != null) {
				String outMessage = textField_SendMessage.getText().toString();
				if (!(outMessage == "")) {
					dataOutputStream.writeUTF(outMessage);
					textArea_out.append("您说:" + outMessage + "\n");
					textField_SendMessage.setText(null);
				} else {
					textArea_out.append("请输入内容后再发送!\n");
				}
			}
		}

	}

	class ClientThread extends Thread {

		@Override
		public void run() {
			while (true) {
				if (socketChat != null) {
					try {
						initStream();
						receiveMessage();
					} catch (IOException e) {
						e.printStackTrace();
						textArea_out.append("与主机失去联系\n");
						try {
							dataInputStream.close();
							dataOutputStream.close();
						} catch (IOException e1) {
							e1.printStackTrace();
							textArea_out.append("与主机失去联系\n");
							return;
						}
						return;
					}
				} else {
					return;
				}
			}
		}

		private void receiveMessage() throws IOException {

			String serverMessage = dataInputStream.readUTF();
			textArea_out.append("服务器说:" + serverMessage + "\n");
		}
	}
}

下面是启动服务器的类

package chatv3.test1.mainapp;

public class ServerApp {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		new ServerMainFrame();
	}

}

下面是服务器类的主体

package chatv3.test1.mainapp;

import java.awt.FileDialog;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.border.TitledBorder;

public class ServerMainFrame {
	private JFrame frameMain;
	private JTextField textField_ServerState;
	private JTextField textField_SendMessage;
	private JPanel panel_left;
	private JButton btnStart;
	private JButton btnClose;
	private JTextArea textArea_out;
	private JButton btnSendMessage;
	// 保存系统 保留的信息 ,暂时不用
	private ArrayList
  
  
   
    SYS_SYMBLO;
	private JMenuBar menuBar;
	private JMenu menuFile;
	private JMenu menuConfig;
	private JMenuItem menuConfigPort;
	private JMenuItem menuFileOpen;
	private JMenuItem menuFileSave;

	private String hostIP;
	private int port = 8888;
	private Socket socket = null;
	private ServerSocket serverSocket = null;
	private DataInputStream inputStream = null;
	private DataOutputStream outputStream = null;

	public ServerMainFrame() {
		frameMain = new JFrame("服务器已关闭");
		frameMain.getContentPane().setLayout(null);
		frameMain.setBounds(300, 300, 786, 380);
		panel_left = new JPanel();
		panel_left.setBorder(new TitledBorder(null, "聊天区域",
				TitledBorder.LEADING, TitledBorder.TOP, null, null));
		panel_left.setBounds(12, 12, 468, 294);
		frameMain.getContentPane().add(panel_left);
		panel_left.setLayout(null);

		JPanel panel_left_startServer = new JPanel();
		panel_left_startServer.setBounds(8, 17, 448, 38);
		panel_left.add(panel_left_startServer);
		panel_left_startServer
				.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));

		JLabel lbl_ServerState = new JLabel("服务器状态");
		panel_left_startServer.add(lbl_ServerState);

		textField_ServerState = new JTextField("已关闭");
		textField_ServerState.setEditable(false);
		panel_left_startServer.add(textField_ServerState);
		textField_ServerState.setColumns(10);

		btnStart = new JButton("打开服务器");
		panel_left_startServer.add(btnStart);

		btnClose = new JButton("关闭服务器");
		btnClose.setEnabled(false);
		panel_left_startServer.add(btnClose);

		JScrollPane scrollPane = new JScrollPane();
		scrollPane.setBounds(8, 65, 448, 189);
		panel_left.add(scrollPane);

		textArea_out = new JTextArea();
		textArea_out.setEditable(false);
		scrollPane.setViewportView(textArea_out);

		JPanel panel_left_SendMessage = new JPanel();
		panel_left_SendMessage.setBounds(8, 259, 448, 23);
		panel_left.add(panel_left_SendMessage);
		panel_left_SendMessage.setLayout(null);

		textField_SendMessage = new JTextField();
		textField_SendMessage.setBounds(0, 0, 331, 21);
		panel_left_SendMessage.add(textField_SendMessage);
		textField_SendMessage.setColumns(10);

		btnSendMessage = new JButton("发送");
		btnSendMessage.setBounds(355, 0, 93, 23);
		panel_left_SendMessage.add(btnSendMessage);

		JPanel panel_right = new JPanel();
		panel_right.setBorder(new TitledBorder(null, "功能区",
				TitledBorder.LEADING, TitledBorder.TOP, null, null));
		panel_right.setBounds(492, 12, 272, 294);
		frameMain.getContentPane().add(panel_right);
		panel_right.setLayout(null);

		JPanel panel_right_funcation = new JPanel();
		panel_right_funcation.setBounds(8, 17, 254, 155);
		panel_right.add(panel_right_funcation);

		menuBar = new JMenuBar();
		frameMain.setJMenuBar(menuBar);

		menuFile = new JMenu("文件");
		menuBar.add(menuFile);

		menuFileOpen = new JMenuItem("打开聊天记录");
		menuFile.add(menuFileOpen);

		menuFileSave = new JMenuItem("保存聊天记录");
		menuFile.add(menuFileSave);

		menuConfig = new JMenu("配置");
		menuBar.add(menuConfig);

		menuConfigPort = new JMenuItem("端口");
		menuConfig.add(menuConfigPort);
		AddListener();
		frameMain.setVisible(true);
		frameMain.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}

	/*
	 * 添加监听器
	 */
	private void AddListener() {
		menuFileOpen.addActionListener(new MenuFileListener());
		menuFileSave.addActionListener(new MenuFileListener());
		menuConfigPort.addActionListener(new MenuConfigListener());

		btnStart.addActionListener(new ServerListener());
		btnClose.addActionListener(new ServerListener());

		btnSendMessage.addActionListener(new SendMessageListener());
		textField_SendMessage.addActionListener(new SendMessageListener());
	}

	private void startServer() {
		new ServerSocketThread().start();
		// TODO 文件接收监听
		new FileReceiveWait();
		try {
			hostIP = getHostIP();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		}
		textArea_out.append("服务器" + hostIP + ":" + port + "已连接\n");
		frameMain.setTitle("服务器已连接" + hostIP + ":" + port);
		textField_ServerState.setText("已启动");
		btnStart.setEnabled(false);
		btnClose.setEnabled(true);
	}

	private String getHostIP() throws UnknownHostException {
		String IP = null;
		IP = InetAddress.getLocalHost().toString();
		return IP;
	}

	/*
	 * 目前有个问题 当已经连接时 如果改变端口号,在关闭服务器时会显示错误的端口
	 */
	private void closeServer() {
		try {
			if (socket != null) {
				socket.close();
			}
			serverSocket.close();
			textArea_out.append("服务器" + hostIP + ":" + port + "已关闭连接\n");
			frameMain.setTitle("服务器已关闭");
		} catch (IOException e1) {
			e1.printStackTrace();
		}
		textField_ServerState.setText("已关闭");
		btnClose.setEnabled(false);
		btnStart.setEnabled(true);
	}

	/*
	 * 按钮btnStart 和 btnClose的监听
	 */
	class ServerListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent arg0) {
			if (arg0.getSource() == btnStart) {
				startServer();
			} else if (arg0.getSource() == btnClose) {
				closeServer();
			}
		}

	}

	/*
	 * 发送信息的按钮和文本域的监听
	 */
	class SendMessageListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent arg0) {
			try {
				sendMessage();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		private void sendMessage() throws IOException {
			if (socket != null) {
				if (textField_SendMessage.getText() != null) {
					String message = textField_SendMessage.getText();
					outputStream.writeUTF(message);
					outputStream.flush();
					textArea_out.append("您说" + message + "\n");
					textField_SendMessage.setText(null);
				} else {
					textArea_out.append("输入内容后再发送!\n");
				}
			} else {
				textArea_out.append("无连接!\n");
			}
		}

	}

	/*
	 * 菜单项目的文件的监听
	 */
	class MenuFileListener implements ActionListener {

		private void saveChatFile() {
			FileDialog fileDialogSave = new FileDialog(frameMain);
			fileDialogSave.setVisible(true);
			if (fileDialogSave.getFile() != null) {
				try {
					File fileOut = new File(fileDialogSave.getDirectory(),
							fileDialogSave.getFile());
					FileWriter fileWriter = new FileWriter(fileOut);
					BufferedWriter bufferedWriter = new BufferedWriter(
							fileWriter);
					bufferedWriter.write(textArea_out.getText().toCharArray());
					bufferedWriter.close();
					fileWriter.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}

		private void openChatFile() {
			FileDialog fileDialogOpen = new FileDialog(frameMain, "打开",
					FileDialog.LOAD);
			fileDialogOpen.setVisible(true);
			if (fileDialogOpen.getDirectory() != null) {
				FileReader fileReader = null;
				try {
					File fileIn = new File(fileDialogOpen.getDirectory(),
							fileDialogOpen.getFile());
					fileReader = new FileReader(fileIn);
					BufferedReader bufferedReader = new BufferedReader(
							fileReader);
					textArea_out.setText("");
					String sReader = null;
					while ((sReader = bufferedReader.readLine()) != null) {
						textArea_out.append(sReader + "\n");
					}
					fileReader.close();
				} catch (FileNotFoundException e1) {
					e1.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}

		@Override
		public void actionPerformed(ActionEvent arg0) {
			if (arg0.getSource() == menuFileOpen) {
				openChatFile();
			} else if (arg0.getSource() == menuFileSave) {
				saveChatFile();
			}
		}

	}

	/*
	 * 菜单项目配置的监听
	 */
	class MenuConfigListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent arg0) {
			if (arg0.getSource() == menuConfigPort) {
				new ConfigFrame();
			}
		}

	}

	class ConfigFrame extends JFrame {
		private static final long serialVersionUID = 1L;
		private JTextField textField;
		private JButton btnOk = new JButton("确定");
		private JButton btnCancel = new JButton("取消");

		public ConfigFrame() {
			setBounds(350, 350, 250, 150);
			setType(Type.UTILITY);
			setTitle("配置端口号");
			setVisible(true);
			setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
			getContentPane().setLayout(null);

			JLabel lblPort = new JLabel("请输入端口号:");
			lblPort.setBounds(10, 10, 84, 15);
			getContentPane().add(lblPort);

			textField = new JTextField();
			textField.setBounds(104, 7, 66, 21);
			getContentPane().add(textField);
			textField.setColumns(10);

			btnOk.setBounds(10, 61, 93, 23);
			btnOk.addActionListener(new ActionListener() {

				@Override
				public void actionPerformed(ActionEvent arg0) {
					try {
						port = Integer.parseInt(textField.getText());
						dispose();
					} catch (NumberFormatException e) {
						e.printStackTrace();
						JOptionPane.showMessageDialog(null, "请输入数字");
					}
				}
			});
			getContentPane().add(btnOk);

			btnCancel.setBounds(130, 61, 93, 23);
			btnCancel.addActionListener(new ActionListener() {

				@Override
				public void actionPerformed(ActionEvent arg0) {
					dispose();
				}
			});
			getContentPane().add(btnCancel);
		}

	}

	/*
	 * 启动线程监听端口目前只能连接一个客户端,还有些问题没有解决
	 */
	class ServerSocketThread extends Thread {

		@Override
		public void run() {
			try {
				serverSocket = new ServerSocket(port);
				while (true) {
					socket = serverSocket.accept();
					inputStream = new DataInputStream(socket.getInputStream());
					outputStream = new DataOutputStream(
							socket.getOutputStream());
					while (true) {
						receiveMessage();
					}

				}
			} catch (IOException e) {
				e.printStackTrace();
			}

		}

		private void receiveMessage() throws IOException {
			// TODO 处理接收到的信息
			String clientMsg = inputStream.readUTF();
			textArea_out.append(socket.getRemoteSocketAddress() + "说:"
					+ clientMsg + "\n");

		}
	}
}
  
  

下面是文件接收中的 监听本来是想着让发送端监听服务器的接收行为,但是由于比较乱而且没有认证,容易出问题,所以换到服务器端监听了

package chatv3.test1.mainapp;

import java.awt.FileDialog;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JProgressBar;
import javax.swing.JTextField;

public class FileReceiveWait {
	private JFrame frame;
	private JTextField textFieldSpeed;

	private ServerSocket serverSocketFile = null;
	private Socket socketFile = null;

	// 与文件有关的
	private File fileReceive = null;
	private FileOutputStream fileOutputStream = null;
	private BufferedOutputStream bufferedOutputStream = null;

	// 与网络有关的
	private DataInputStream dataInputStream = null;
	private DataOutputStream dataOutputStream = null;
	private BufferedInputStream bufferedInputStream = null;
	private String fileName = null;
	private long fileLength = 0;
	private JProgressBar progressBar;
	private JButton btnTerminate;
	private boolean receiveOk = false;

	public FileReceiveWait() {
		frame = new JFrame("接收文件");
		frame.setBounds(120, 120, 470, 100);
		frame.setResizable(false);
		frame.getContentPane().setLayout(
				new FlowLayout(FlowLayout.CENTER, 5, 5));

		progressBar = new JProgressBar();
		progressBar.setStringPainted(true);
		frame.getContentPane().add(progressBar);

		textFieldSpeed = new JTextField("理论上这里显示的是速度");
		textFieldSpeed.setEditable(false);
		frame.getContentPane().add(textFieldSpeed);
		textFieldSpeed.setColumns(10);

		btnTerminate = new JButton("终止");
		frame.getContentPane().add(btnTerminate);

		frame.setVisible(false);
		frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		addListener();
		new FileReceiveThreadWait().start();
	}

	private void closeStream() throws IOException {
		bufferedOutputStream.flush();
		dataOutputStream.flush();
		dataOutputStream.close();
		bufferedOutputStream.close();
		fileOutputStream.close();
	}

	private void addListener() {
		btnTerminate.addActionListener(new btnListener());
	}

	class btnListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent arg0) {
			if (arg0.getSource() == btnTerminate) {
				int n = JOptionPane.showConfirmDialog(frame, "确定终止吗?",
						"终止文件传输", JOptionPane.YES_NO_OPTION);
				if (n == JOptionPane.YES_OPTION) {
					try {
						socketFile.close();
						JOptionPane.showMessageDialog(frame, "文件传输中止!"
								+ "文件已传输" + progressBar.getValue() + "%");
						frame.setVisible(false);
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}
		}

	}

	class FileReceiveThreadWait extends Thread {

		@Override
		public void run() {
			try {
				serverSocketFile = new ServerSocket(8887);
				while (true) {
					socketFile = serverSocketFile.accept();
					bufferedInputStream = new BufferedInputStream(
							socketFile.getInputStream());
					dataInputStream = new DataInputStream(bufferedInputStream);
					fileName = dataInputStream.readUTF();
					fileLength = dataInputStream.readLong();
					double fileLengthShow = 0;
					int n = 0;
					// 如果大于1GB,1MB,1KB
					if (fileLength > 1024 * 1024 * 1024) {
						fileLengthShow = (fileLength / (1024.0 * 1024.0 * 1024.0));
						n = JOptionPane
								.showConfirmDialog(frame, "客户端发送文件" + fileName
										+ "大小" + fileLengthShow + "GB"
										+ ",是否接收?", "接收文件确认",
										JOptionPane.YES_NO_OPTION);
					} else if (fileLength > 1024 * 1024) {
						fileLengthShow = (fileLength / (1024.0 * 1024.0));
						n = JOptionPane
								.showConfirmDialog(frame, "客户端发送文件" + fileName
										+ "大小" + fileLengthShow + "MB"
										+ ",是否接收?", "接收文件确认",
										JOptionPane.YES_NO_OPTION);
					} else if (fileLength > 1024) {
						fileLengthShow = (fileLength / (1024.0 ));
						n = JOptionPane
								.showConfirmDialog(frame, "客户端发送文件" + fileName
										+ "大小" + fileLengthShow + "KB"
										+ ",是否接收?", "接收文件确认",
										JOptionPane.YES_NO_OPTION);
					} else if (fileLength < 1024) {
						fileLengthShow = fileLength;
						n = JOptionPane
								.showConfirmDialog(frame, "客户端发送文件" + fileName
										+ "大小" + fileLengthShow + "B"
										+ ",是否接收?", "接收文件确认",
										JOptionPane.YES_NO_OPTION);
					}
					if (n == JOptionPane.YES_OPTION) {
						selectFile();
					} else {
						socketFile.close();
					}
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		private void selectFile() {
			FileDialog dialog = new FileDialog(frame, "保存位置", FileDialog.SAVE);
			dialog.setFile(fileName);
			dialog.setVisible(true);
			if (dialog.getFile() != null) {
				fileReceive = new File(dialog.getDirectory() + dialog.getFile());
				new FileReceiveThread().start();
				frame.setVisible(true);
			}
		}
	}

	class FileReceiveThread extends Thread {

		@Override
		public void run() {
			try {

				fileOutputStream = new FileOutputStream(fileReceive);
				bufferedOutputStream = new BufferedOutputStream(
						fileOutputStream);
				dataOutputStream = new DataOutputStream(bufferedOutputStream);
				int n = 0;
				int progress = 0;
				int i = 1;
				while ((n = dataInputStream.read()) != -1) {
					i++;
					progress = (int) (100 * (i * 1.0 / fileLength));
					progressBar.setValue(progress);
					dataOutputStream.write(n);
					if (i == fileLength) {
						JOptionPane.showMessageDialog(frame, "文件传输完成");
						receiveOk = true;
						closeStream();
						frame.dispose();
					}
				}
				closeStream();
			} catch (UnknownHostException e) {
				e.printStackTrace();
			} catch (IOException e) {
				if (receiveOk) {
				} else {
					JOptionPane.showMessageDialog(frame, "文件传输终止!");
				}
				e.printStackTrace();
			}
		}
	}
}

文件发送

package chatv3.test1.mainapp;

import java.awt.FileDialog;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JProgressBar;
import javax.swing.JTextField;

public class FileSend {
	// 与文件有关的
	private File fileout = null;
	private FileInputStream fileInputStream = null;
	private BufferedInputStream bufferedInputStreamFile = null;
	private long fileLength;
	private String fileName = null;
	// 与网络有关的
	private DataInputStream inputStream = null;
	private DataOutputStream outputStream = null;
	private BufferedOutputStream bufferedOutputStreamNet = null;

	private JFrame frameMain = null;
	private JTextField textFieldSelect;
	private JButton btnSelect;
	private JProgressBar progressBar;
	private JButton btnCancel;
	private JButton btnSend;

	private int port;
	private String ipString = null;
	private Socket socket = null;
	private boolean sendOk = false;

	public FileSend(String ipString, int port) {
		this.ipString = ipString;
		this.port = port;
		frameMain = new JFrame("发送文件");
		frameMain.setResizable(true);
		frameMain.getContentPane().setLayout(null);
		frameMain.setBounds(120, 120, 530, 260);
		frameMain.setVisible(true);
		frameMain.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		JLabel lblSelectFile = new JLabel("请选择要发送的文件:");
		lblSelectFile.setBounds(10, 34, 178, 15);
		frameMain.getContentPane().add(lblSelectFile);

		textFieldSelect = new JTextField();
		textFieldSelect.setBounds(177, 31, 213, 21);
		frameMain.getContentPane().add(textFieldSelect);
		textFieldSelect.setColumns(10);

		btnSelect = new JButton("浏览");
		btnSelect.setBounds(409, 30, 93, 23);
		frameMain.getContentPane().add(btnSelect);

		btnSend = new JButton("发送");
		btnSend.setBounds(409, 81, 93, 23);
		frameMain.getContentPane().add(btnSend);

		btnCancel = new JButton("取消");
		btnCancel.setBounds(409, 138, 93, 23);
		frameMain.getContentPane().add(btnCancel);

		progressBar = new JProgressBar();
		progressBar.setStringPainted(true);
		progressBar.setBounds(26, 112, 364, 19);
		frameMain.getContentPane().add(progressBar);
		addListener();
		frameMain.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
	}

	public long getFileLength() {
		return fileLength;
	}

	public String getFileName() {
		return fileName;
	}

	private void closeStream() throws IOException {
		outputStream.flush();
		outputStream.close();
		bufferedOutputStreamNet.flush();
		bufferedOutputStreamNet.close();
		bufferedInputStreamFile.close();
		fileInputStream.close();
	}

	private void addListener() {
		btnSelect.addActionListener(new BtnListener());
		btnSend.addActionListener(new BtnListener());
		btnCancel.addActionListener(new BtnListener());
	}

	/*
	 * 监听点击按钮后的事件
	 */
	class BtnListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent arg0) {
			if (arg0.getSource() == btnSelect) {
				selectFile();
			} else if (arg0.getSource() == btnSend) {
				sendFile();
				btnSelect.setEnabled(false);
				btnSend.setEnabled(false);
			} else if (arg0.getSource() == btnCancel) {
				int n = JOptionPane.showConfirmDialog(frameMain, "确定终止吗?",
						"终止文件传输", JOptionPane.YES_NO_OPTION);
				if (n == JOptionPane.YES_OPTION) {
					try {
						socket.close();
						JOptionPane.showMessageDialog(frameMain, "文件传输中止!"
								+ "文件已传输" + progressBar.getValue() + "%");
						frameMain.setVisible(false);
					} catch (IOException e) {
						e.printStackTrace();
					}
					frameMain.dispose();
				}
			}
		}

		private void selectFile() {

			FileDialog fileDialog = new FileDialog(frameMain, "选择文件",
					FileDialog.LOAD);
			fileDialog.setVisible(true);

			if (fileDialog.getFile() != null) {
				String fileName = fileDialog.getDirectory()
						+ fileDialog.getFile();
				textFieldSelect.setText(fileName);
				try {
					fileout = new File(fileName);
					fileInputStream = new FileInputStream(fileout);
					bufferedInputStreamFile = new BufferedInputStream(
							fileInputStream);
				} catch (FileNotFoundException e) {
					e.printStackTrace();
				}
			}
		}

		private void sendFile() {
			try {
				socket = new Socket(ipString, port);
				new FileSendThread().start();
			} catch (UnknownHostException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

	}

	class FileSendThread extends Thread {
		@Override
		public void run() {
			if (fileout != null) {
				try {
					// TODO 获取文件长度和名称 接收时使用
					fileLength = fileout.length();
					fileName = fileout.getName();
					inputStream = new DataInputStream(socket.getInputStream());
					bufferedOutputStreamNet = new BufferedOutputStream(
							socket.getOutputStream());
					outputStream = new DataOutputStream(bufferedOutputStreamNet);
					int n = 0;
					int i = 0;
					int progress = 0;
					// TODO 首先 发送文件名和长度
					outputStream.writeUTF(fileName);
					outputStream.writeLong(fileLength);

					while ((n = bufferedInputStreamFile.read()) != -1) {
						i++;
						progress = (int) (100 * (i * 1.0 / fileLength));
						progressBar.setValue(progress);
						outputStream.write(n);
						if (i == fileLength) {
							sendOk = true;
							JOptionPane.showMessageDialog(frameMain, "发送完成");
							closeStream();
							frameMain.dispose();
						}
					}
					closeStream();

				} catch (IOException e) {
					if (sendOk) {
					} else {
						JOptionPane.showMessageDialog(frameMain, "文件传输终止"
								+ "文件已传输" + progressBar.getValue() + "%"
								+ fileLength * (progressBar.getValue() / 100.0)
								+ "B");
						frameMain.dispose();
					}
					e.printStackTrace();
				}
			}
		}

	}
}




  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值