您的位置:首页 > 编程语言 > Java开发

哈工大 java实验4 基于socket的消息发送与文件传输

2011-10-26 21:55 405 查看
这次试验比较难,套接字这东西不好调试,很蛋疼。

首先是套接字,java的套接字封装的比较好,简单易用。

客户端这样写:

try {
					Socket socket = new Socket(IP_Address,Port);
					BufferedReader socketReader = new BufferedReader(
							new InputStreamReader(socket.getInputStream()));
					BufferedWriter socketWrite = new BufferedWriter(
							new OutputStreamWriter(socket.getOutputStream()));
					socketWrite.write("yourString");
					socketWrite.flush();
				} catch (UnknownHostException e1) {
					System.out
							.println("Error setting up socket connection: unknown host at "
									+ IP_Address + ":" +Port);
				} catch (IOException e2) {
					System.out.println("Error setting up socket connection: "
							+ e);
				}


异常抛出的时候,输出个字符串,有益于调试。

关于这个BufferedReader的封装,

在java里inputStream,outputStream这类的东西,一般用来处理8位的流,ASCII,字符,二进制,一般用这个

Reader,Writer用来处理16位的流,就是Unicode之类的。

而且有一个,InputStreamReader,OutStreamReader 负责二者之间的转换。

其中我经常用这个 BufferedReader 和 这个 DataInputStream,后者有getInt()之类的方法比较好用。

服务端这样写

public void run() {
				try {
					server = new ServerSocket(textReceivePort);
					while (running) {                                 //线程运行时在外部吧running改成false可终止线程运行
						System.out.println("inThread!");
						incomingConnection = server.accept();
						System.out.println("HaveAccept!");
						BufferedReader socketReader = new BufferedReader(
								new InputStreamReader(
										incomingConnection.getInputStream()));
						String t;
						t = socketReader.readLine();
						if (t != null)
							chatArea.append(t + "\n");

						socketReader.close();
						System.out.println("message up!");
					}
				} catch (BindException e) {
					System.out.println("Unable to bind to port "
							+ textReceivePort);
				} catch (IOException e) {
					System.out
							.println("Unable to instantiate a ServerSocket on port: "
									+ textReceivePort);
				}
			}


重点是不要忘记停掉不用的线程。。。。。。。。不然会出现好几十个线程在跑,占用一大堆端口的情况。

平常只要把running设成false,让线程自己跑完就可以了,

执行server.accept这一句时,线程会原地等待,这时候想终止线程,需要调用,interrupt()方法使线程抛出异常而停止。

stop()方法已经被弃用了,最好不要使用,关于为什么弃用,核心技术上有详细讲解。

布局方面,需要一个菜单栏,java提供了相关的类,很轻松就可以写好

JMenuBar menuBar = new JMenuBar();
			JMenu sysMenu = new JMenu("System");
			JMenuItem Item_Setting = new JMenuItem("Setting");
			JMenuItem Item_Exit = new JMenuItem("Exit");
			Item_Setting.addActionListener(new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent event) {
					
				}
			});
			Item_Exit.addActionListener(new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent event) {
					
				}
			});
			sysMenu.add(Item_Setting);
			sysMenu.add(Item_Exit);
			menuBar.add(sysMenu);
			setJMenuBar(menuBar);
设置界面我直接使用了另一个JFrame,在响应里把它设成可见就可以了。

最后关闭程序时,一定要把,所有的线程和套接字都关掉。

protected void processWindowEvent(WindowEvent e) {
			if (e.getID() == WindowEvent.WINDOW_CLOSING) {
				stopRun(messageRun);
				stopRun(fileRun);
				System.exit(0);
			}
		}


这样基本功能就都实现了,

不过,我发现在释放掉socket之后,他所绑定的端口不会立即被释放掉,调试的时候蛋疼了一阵,谁有解决方发请留言告知。

还有,我使用BufferedWriter,和,BufferedReader,实现传输文件时会因为编码格式不同而产生乱码,比如“UTF-8”的就正常,而“”GBK“的就是乱码。

大概用Stream按bytes传就不会有问题,不过懒得写了。

最后贴上源码

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.BindException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;

import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.border.TitledBorder;

public class MyQQ {
public static void main(String[] args) {
MF = new MainFrame();
}

private static class AbstractFrame extends JFrame {
public AbstractFrame(String name) {
super(name);
}

protected void setCons(int x, int y, int z, int k) {
cons.gridx = x;
cons.gridy = y;
cons.gridwidth = z;
cons.gridheight = k;
}

protected void init() {

cons.weightx = 1;
cons.weighty = 1;
}

protected GridBagConstraints cons = new GridBagConstraints();
}

private static class MainFrame extends AbstractFrame implements
ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
if (source.equals(sentChat)) {
try {
System.out.println("inAction");
Socket socket = new Socket(IP_Address, textSendPort);
BufferedReader socketReader = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
BufferedWriter socketWrite = new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream()));
socketWrite.write(textNickName.getText() + ":"
+ sendArea.getText() + "\n");
socketWrite.flush();
System.out.println(messageRun.getState());
} catch (UnknownHostException e1) {
System.out
.println("Error setting up socket connection: unknown host at "
+ IP_Address + ":" + textReceivePort);
} catch (IOException e2) {
System.out.println("Error setting up socket connection: "
+ e);
}
} else if (source.equals(sentFile)) {
JFileChooser fDialog = new JFileChooser();
fDialog.setDialogTitle("Choose File To Send");
int returnVal = fDialog.showOpenDialog(null);
if (JFileChooser.APPROVE_OPTION == returnVal) {
//receiveFile.setEnabled(true);
try {
Socket socket = new Socket(IP_Address, fileSendPort);
srcFile = fDialog.getSelectedFile().getPath();
fileName = fDialog.getSelectedFile().getName();
File inFile = new File(srcFile);
BufferedWriter socketWrite = new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream()));
BufferedReader in = new BufferedReader(
new InputStreamReader(new FileInputStream(
inFile), "UTF-8"));
System.out.println("chooesed file");
char[] tempbytes = new char[1000];
String tempbyte;

fileRow = 0;
while ((tempbyte = in.readLine()) != null) {
fileRow++;
System.out.println(tempbyte + "\n");
socketWrite.write(tempbyte + "\r");
socketWrite.flush();
}
System.out.println("W_row" + fileRow);
in.close();
socketWrite.close();
socket.close();
} catch (UnknownHostException e1) {
System.out
.println("Error setting up socket connection: unknown host at "
+ IP_Address + ":" + textReceivePort);
} catch (IOException e2) {
System.out
.println("Error setting up socket connection: When send file");
}
}

} else if (source.equals(receiveFile)) {
receiveFile.setEnabled(false);
fileRun.hanging = false;
}
}

private class MyThread extends Thread {
public boolean running = true;
public ServerSocket server;
public Socket incomingConnection = null;
boolean changePort = true;
public boolean hanging = true;
}

private class MessageListener extends MyThread {
@Override
public void run() {
try {
server = new ServerSocket(textReceivePort);
while (running) {
System.out.println("inThread!");
incomingConnection = server.accept();
System.out.println("HaveAccept!");
BufferedReader socketReader = new BufferedReader(
new InputStreamReader(
incomingConnection.getInputStream()));
String t;
t = socketReader.readLine();
if (t != null)
chatArea.append(t + "\n");

socketReader.close();
System.out.println("message up!");
}
} catch (BindException e) {
System.out.println("Unable to bind to port "
+ textReceivePort);
} catch (IOException e) {
System.out
.println("Unable to instantiate a ServerSocket on port: "
+ textReceivePort);
}
}

}

private class FileListener extends MyThread {
@Override
public void run() {
try {
server = new ServerSocket(fileReceivePort);
while (running) {
System.out.println("inThreadFile!");
incomingConnection = server.accept();
System.out.println("HaveFileAccept!");
BufferedReader socketReader = new BufferedReader(
new InputStreamReader(
incomingConnection.getInputStream(),
"UTF-8"));
receiveFile.setEnabled(true);
hanging = true;
while (hanging) {

}
System.out.println("rece File~");

File outFile = new File("DownLoad");
BufferedWriter os = new BufferedWriter(
new OutputStreamWriter(new FileOutputStream(
outFile)));
char[] tempbytes = new char[1000];
String tempbyte;

while ((socketReader.readLine())!=null) {
tempbyte = socketReader.readLine();
os.write(tempbyte);
os.flush();
}
os.close();
socketReader.close();
}

} catch (BindException e) {
System.out.println("FileListener Unable to bind to port "
+ fileReceivePort);
} catch (IOException e) {
System.out
.println("Unable to instantiate a ServerSocket on port: "
+ fileReceivePort);
}
}

}

public MainFrame() {
super("Main");
init();

setLayout(new GridBagLayout());

setCons(0, 0, 5, 5);
add(chatArea, cons);
setCons(0, 5, 1, 1);
add(nickName, cons);
setCons(1, 5, 4, 1);
add(textNickName, cons);
setCons(0, 6, 5, 3);
add(sendArea, cons);
setCons(0, 9, 2, 1);
add(sentFile, cons);
setCons(2, 9, 2, 1);
add(receiveFile, cons);
setCons(4, 9, 1, 1);
add(sentChat, cons);

setSize(300, 600);
this.setVisible(true);
}

@Override
protected void processWindowEvent(WindowEvent e) { if (e.getID() == WindowEvent.WINDOW_CLOSING) { stopRun(messageRun); stopRun(fileRun); System.exit(0); } }

protected void init() {
super.init();
upDate();
FlashState();
menuBar = new JMenuBar();
sysMenu = new JMenu("System");
Item_Setting = new JMenuItem("Setting");
Item_Exit = new JMenuItem("Exit");
Item_Setting.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
SF = new SettingFrame();
}
});
Item_Exit.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
System.out.print("bbb");
}
});
sysMenu.add(Item_Setting);
sysMenu.add(Item_Exit);
menuBar.add(sysMenu);
setJMenuBar(menuBar);

chatArea.setBorder(new TitledBorder(""));
sendArea.setBorder(new TitledBorder(""));
receiveFile.setEnabled(false);
sentFile.addActionListener(this);
receiveFile.addActionListener(this);
sentChat.addActionListener(this);
}

public void FlashState() {
upDateToFile();
System.out.println("FlashState!");
stopRun(messageRun);
messageRun = new MessageListener();
messageRun.start();
stopRun(fileRun);
fileRun = new FileListener();
fileRun.start();

}

private void upDate() {
File configFile = new File("ConfigFile.txt");
if (configFile.exists()) {
try {
BufferedReader in = new BufferedReader(new FileReader(
configFile));
textReceivePort = Integer.parseInt(in.readLine());
fileReceivePort = Integer.parseInt(in.readLine());
textSendPort = Integer.parseInt(in.readLine());
fileSendPort = Integer.parseInt(in.readLine());
IP_Address = in.readLine();
in.close();
} catch (IOException e) {

}
} else {
upDateToFile();
}

}

private void upDateToFile() {
File configFile = new File("ConfigFile.txt");
try {
BufferedWriter out = new BufferedWriter(new FileWriter(
configFile));
out.write(textReceivePort + "\r");
out.write(fileReceivePort + "\r");
out.write(textSendPort + "\r");
out.write(fileSendPort + "\r");
out.write(IP_Address + "\r");
out.close();
} catch (IOException e) {

}
}

private void stopRun(MyThread t) {
if (t != null) {
t.running = false;
t.changePort = false;
t.hanging = false;
t.interrupt();
}
}

private MessageListener messageRun = null;
private FileListener fileRun = null;
private static String srcFile;
private static String fileName = "downLoad";
private static int fileRow;
private JMenuBar menuBar;
private JMenu sysMenu;
private JMenuItem Item_Setting;
private JMenuItem Item_Exit;

private JTextArea chatArea = new JTextArea(10, 20);
private JTextArea sendArea = new JTextArea(5, 20);
private JLabel nickName = new JLabel("NickName:");
private JTextField textNickName = new JTextField(15);
private JButton sentFile = new JButton("SendFile");
private JButton receiveFile = new JButton("receiveFile");
private JButton sentChat = new JButton("send");
}

private static class SettingFrame extends AbstractFrame implements
ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
if (source.equals(submit)) {
textReceivePort = Integer.parseInt(Text_1.getText());
fileReceivePort = Integer.parseInt(Text_2.getText());
String IP_Address = Text_3.getText();
textSendPort = Integer.parseInt(Text_4.getText());
fileSendPort = Integer.parseInt(Text_5.getText());
dispose();
MF.FlashState();
} else if (source.equals(cancel)) {
dispose();
}
}

public SettingFrame() {
super("Setting");
init();
setLayout(new GridBagLayout());
// ----------------------------------------
setCons(0, 0, 2, 1);
add(label_1, cons);
setCons(2, 0, 2, 1);
add(Text_1, cons);
// ----------------------------------------
setCons(0, 1, 2, 1);
add(label_2, cons);
setCons(2, 1, 2, 1);
add(Text_2, cons);
// ----------------------------------------
setCons(0, 2, 2, 1);
add(label_3, cons);
setCons(2, 2, 2, 1);
add(Text_3, cons);
// ----------------------------------------
setCons(0, 3, 2, 1);
add(label_4, cons);
setCons(2, 3, 2, 1);
add(Text_4, cons);
// ----------------------------------------
setCons(0, 4, 2, 1);
add(label_5, cons);
setCons(2, 4, 2, 1);
add(Text_5, cons);
// ----------------------------------------
setCons(1, 5, 1, 1);
add(submit, cons);
setCons(2, 5, 1, 1);
add(cancel, cons);
// ----------------------------------------
setSize(300, 300);
this.setVisible(true);
}

protected void init() {
super.init();
submit.addActionListener(this);
cancel.addActionListener(this);
Text_1.setText(textReceivePort + "");
Text_2.setText(fileReceivePort + "");
Text_3.setText(IP_Address);
Text_4.setText(textSendPort + "");
Text_5.setText(fileSendPort + "");

}

private JLabel label_1 = new JLabel("Text Receive Port:");
private JLabel label_2 = new JLabel("File Receive Port:");
private JLabel label_3 = new JLabel("Send IP:");
private JLabel label_4 = new JLabel("Text Send Port:");
private JLabel label_5 = new JLabel("File Send Port:");
private JTextField Text_1 = new JTextField(10);
private JTextField Text_2 = new JTextField(10);
private JTextField Text_3 = new JTextField(10);
private JTextField Text_4 = new JTextField(10);
private JTextField Text_5 = new JTextField(10);
private JButton submit = new JButton("Submit");
private JButton cancel = new JButton("Cancel");
}

private static MainFrame MF;
private static SettingFrame SF;
private static String IP_Address = "127.0.0.1";
private static int textReceivePort = 5555;
private static int fileReceivePort = 6666;
private static int textSendPort = 5555;
private static int fileSendPort = 6666;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: