基于GUI的网络通信程序设计
一、实验目的
1.掌握Java中GUI程序的编写,包括事件监听机制。
2.掌握Java的网络通信编程,ServerSocket,Socket类的使用。
3.掌握Java中多线程的编程,Thread类,Runnable接口的使用。
4.掌握用面向对象的方法分析和解决复杂问题。
二、实验原理
1.通过Thread建立多线程实现双向通信。
2.通过Socket类来实现客户端与服务器的连接。
3.通过继承JFrame类来创建图形化界面。
4.通过动作监听器来实现各个按钮的操作。
三、实验过程、步骤及原始记录(算法、原程序、测试结果,分析等)
1、创建各个文本框进行消息的存储与显示。
2、建立监听器与建立端口与连接。
3、建立文本框的消息传送方式。
4、重新定义多线程的run函数。
5、开启端口等待客户端的连接。
6、等待客户端消息并显示消息。
7、开启客户端并且启动连接。
8、接受服务器端的消息并显示。
服务器代码:
package Server;
import java.io.*;
import java.net.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class ServerUI extends JFrame {
JTextArea mainArea;//主文本框
JTextField sendArea;//端口文本框
JTextField indexArea;//消息文本框
SvrCom server;//线程对象
public void setServer(SvrCom server) {
this.server = server;
}
public ServerUI() {
super("服务器");
Container contain = getContentPane();
contain.setLayout(new BorderLayout());//布局器
mainArea = new JTextArea(10,30);//10行的多行文本
JScrollPane mainAreaP = new JScrollPane(mainArea);
JPanel panel = new JPanel();
JPanel myPanel=new JPanel();
//端口文本框内容及布局。
JLabel myLabel2=new JLabel("端口:",SwingConstants.LEFT);
JTextField myField1=new JTextField(30);
JButton button1=new JButton("Start");
//监听器判断是否开始连接。
button1.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae) {
server.sendMsg("PORT:1234");
mainArea.append("服务开始>>>" + "\n");
sendArea.setText("");
}
});
//端口文本框添加到布局器中。
myField1.setText("1234");
myPanel.add(myLabel2);
myPanel.add(myField1);
myPanel.add(button1);
panel.setLayout(new BorderLayout());
sendArea = new JTextField(25);//新建发送消息框
JButton sendBtn = new JButton("发送");
sendBtn.addActionListener(new ActionListener()// 注册动作监听器
{
public void actionPerformed(ActionEvent ae) {
server.sendMsg(sendArea.getText());// 把信息传递到客户端
mainArea.append("服务器:" + sendArea.getText() + "\n");// 把信息显示在服务器的聊天记录区域
sendArea.setText("");
}
});
//主文本框及框架的布局。
panel.add(new JLabel("Say:"),BorderLayout.WEST);
panel.add(sendBtn, BorderLayout.EAST);
panel.add(sendArea, BorderLayout.CENTER);
contain.add(myPanel, BorderLayout.NORTH);
contain.add(mainAreaP, BorderLayout.CENTER);
contain.add(panel, BorderLayout.SOUTH);
setSize(500, 300);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
}
public static void main(String[] args) {
ServerUI ui = new ServerUI();
SvrCom server = new SvrCom(ui);// 创建并启动网络通讯线程,准备接受客户端数据包
}
}
class SvrCom extends Thread
{
Socket client;
ServerSocket soc;
BufferedReader in;
PrintWriter out;
ServerUI ui;
public SvrCom(ServerUI ui) { // 构造函数
this.ui = ui;
ui.setServer(this);
try {
soc = new ServerSocket(1234); // 开设服务器端口1234
System.out.println("启动服务器成功,等待端口号:1234");
client = soc.accept();// 与客户端开启连接。
System.out.println("连接成功!来自" + client.toString());
//读入客户端的消息。
in = new BufferedReader(new InputStreamReader(client.getInputStream()));
//将消息发出。
out = new PrintWriter(client.getOutputStream(), true);
} catch (Exception ex) {
System.out.println(ex);
}
start();
}
public void run() {// 重新定义run函数
String msg = "";
while (true) {
try {
msg = in.readLine();// 从in对象上读数据信息
} catch (SocketException ex) {
System.out.println(ex);
break;
} catch (Exception ex) {
System.out.println(ex);
}
//判断消息不为空则输出消息。
if (msg != null && msg.trim() != "") {
System.out.println(">>" + msg);
ui.mainArea.append(msg + "\n");
}
}
}
public void sendMsg(String msg) {//在服务器界面显示输出消息
try {
out.println("服务器:" + msg);
} catch (Exception e) {
System.out.println(e);
}
}
}
客户端代码:
package Server;
import java.io.*;
import java.net.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class ClientUI extends JFrame {
JTextArea mainArea;
JTextField sendArea;
ChatClient client;
JTextField ipArea;
JTextField portArea;
JButton btnLink;
//构造函数
public void setClient(ChatClient client){
this.client = client;
}
public ClientUI() {
super("客户端");
Container contain = getContentPane();
contain.setLayout(new BorderLayout());
mainArea = new JTextArea(10,30);//多行文本框
JScrollPane mainAreaP = new JScrollPane(mainArea);
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
sendArea = new JTextField(25);//发送文本框
JButton sendBtn = new JButton("发送");
//监听连接消息。
sendBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
client.sendMsg(sendArea.getText());
mainArea.append("客户端:" + sendArea.getText() + "\n");
sendArea.setText("");
}
});
JPanel ipPanel = new JPanel();
ipPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 10, 10));
//连接消息文本框及布局。
ipPanel.add(new JLabel("Server IP:"));
ipArea = new JTextField(15);
ipArea.setText("127.0.0.1");
ipPanel.add(ipArea);
ipPanel.add(new JLabel("端口:"));
portArea =new JTextField(8);
ipPanel.add(portArea);
btnLink = new JButton("连接!");
ipPanel.add(btnLink);
//连接按钮的监听器。
btnLink.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
String port=portArea.getText();
//判断端口是否正确。
if( port.equals( "1234")){
mainArea.append("连接成功" + "\n");
client = new ChatClient(ipArea.getText(), 1234, ClientUI.this);
ClientUI.this.setClient(client);
}
else {
mainArea.append("端口错误" + "\n");
}
}
});
//发送文本框及布局。
panel.add(new JLabel("Say:"),BorderLayout.WEST);
panel.add(sendBtn, BorderLayout.EAST);
panel.add(sendArea, BorderLayout.CENTER);
//主文本框布局。
contain.add(ipPanel, BorderLayout.NORTH);
contain.add(mainAreaP, BorderLayout.CENTER);
contain.add(panel, BorderLayout.SOUTH);
setSize(500, 300);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
}
public static void main(String[] args) {
ClientUI ui = new ClientUI();
}
}
class ChatClient extends Thread {
Socket sc;
BufferedReader in;
PrintWriter out;
ClientUI ui;
//构造函数
public ChatClient(String ip, int port, ClientUI ui) {
this.ui = ui;
try {
sc = new Socket(ip, port);
//发送信息。
out = new PrintWriter(sc.getOutputStream(), true);
//读取信息。
in = new BufferedReader(new InputStreamReader(sc.getInputStream()));
} catch (Exception e) {
System.out.println(e);
}
start();
}
//重新定义run函数。
public void run() {
String msg = "";
while (true) {
try {
msg = in.readLine();
} catch (SocketException ex) {
System.out.println(ex);
break;
} catch (Exception ex) {
System.out.println(ex);
}
//判断服务器发送信息是否为空。
if (msg != null && msg.trim() != "") {
System.out.println(">>" + msg);
ui.mainArea.append(msg + "\n");
}
}
}
public void sendMsg(String msg) {
try {
out.println("客户端:" + msg);
} catch (Exception e) {
System.out.println(e);
}
}
}