最近我刚刚学习了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();
}
}
}
}
}