一.实验目的
1.掌握Java中GUI程序的编写,包括事件监听机制。
2.掌握Java的网络通信编程,ServerSocket,Socket类的使用。
3.掌握Java中多线程的编程,Thread类,Runnable接口的使用。
4.掌握用面向对象的方法分析和解决复杂问题。
二.实验内容
编写程序完成以下功能:
1.设计一个基于GUI的客户-服务器的通信应用程序,如图1,图2所示。
图1 Socket通信服务器端界面
图2 Socket通信客户端界面
-
图1为Socket通信服务器端界面,点击该界面中的【Start】按钮,启动服务器监听服务(在图1界面中间的多行文本区域显示“Server starting…”字样)。
-
图2为Socket通信客户端界面,点击该界面中的【Connect】按钮与服务器建立链接,并在图2所示界面中间的多行文本区域显示“Connect to server…”字样
-
当服务器端监听到客户端的连接后,在图1界面中间的多行文本区域追加一行“Client connected…”字样,并与客户端建立Socket连接。
-
当图1所示的服务器端和图2所示的客户机端建立Socket连接后,编程实现服务端、客户端之间的“单向通信”:在客户端的输入界面发送消息,在服务端接收该消息,并将接收到对方的数据追加显示在多行文本框中。
-
在完成上述实验内容的基础上,尝试实现“双向通信”功能,即服务端、客户端之间可以相互发送、接收消息
基本思路
- 服务器和客户端之前分开写一个java
- 依靠Socket和ServerSocket()实现客户端和服务器之前的连接
- GUI的基本知识actionPerformed()
- 保证双向连接,使用线程,读入会阻塞线程,有多次读入,不用线程会一直卡住
while(tem) {tem=reader.read();}
- 基本的文件流读入输出
InputStream ios = this.Client.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(ios));
详情可见JAVA学习
代码实例
ServerFrame.java
package Research_3;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerFrame extends Frame implements ActionListener{
Label [] labels = new Label[5];
TextField [] textFields = new TextField[5];
Button [] buttons = new Button[5];
TextArea [] textAreas= new TextArea[5];
Panel [] panels = new Panel[5];
ServerSocket listen1=null;
Socket Client=null;
//Choice ClientChoice = new Choice();
//HashMap<String,Socket> socketHashMap = new HashMap<String, Socket>();
public ServerFrame(String title){//构造函数
super(title);
}
public static void main(String[] args) {
ServerFrame f= new ServerFrame("Server");
f.DrawGUI();
}
void DrawGUI() {//基本绘图
labels[0] = new Label("Port:");
labels[1] = new Label("Say:");
textFields[0] = new TextField(80);
textFields[1] = new TextField(80);
buttons[0] = new Button(" start ");
buttons[1] = new Button(" Say ");
textAreas[0] =new TextArea(8,80);
panels[0] = new Panel();
panels[1] = new Panel();
for(int i =0;i<=1;++i){
panels[i].add(labels[i]);panels[i].add(textFields[i]);panels[i].add(buttons[i]);
}
add(panels[0],"North");
add(panels[1],"South");
add(textAreas[0],"Center");
pack();
setVisible(true);
buttons[0].addActionListener(this);//绑定按钮和事件
buttons[1].addActionListener(this);
}
@Override
public void actionPerformed(ActionEvent e) {
Object source =e.getSource();
if(source == buttons[0]) {
try {
int port = Integer.parseInt(textFields[0].getText().trim());
textAreas[0].append("Server starting…"+'\n');
listen1 = new ServerSocket(port);
Client = listen1.accept();
textAreas[0].append("Client connected…"+'\n');
Thread ServerListen = new Thread(new Server_ListenThread(Client));
ServerListen.start();//开始Server的读入线程
} catch (Exception e1) {
e1.printStackTrace();
}
}else{
Thread ServerSpeaker = new Thread(new Server_Speaker(Client));
ServerSpeaker.start();//开始Server的讲话线程
}
}
class Server_ListenThread implements Runnable{实现Runnable接口实现run函数
Socket Client;
public Server_ListenThread(Socket Client){
this.Client=Client;
}
@Override
public void run() {
try {
InputStream ios = this.Client.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(ios));
String tem =reader.readLine();
while(tem!=null){
textAreas[0].append("Form Client:"+tem+'\n');
tem=reader.readLine();
}
reader.close();
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
class Server_Speaker implements Runnable{
Socket Client;
public Server_Speaker(Socket Client){
this.Client=Client;
}
@Override
public void run() {
try {
OutputStream os = Client.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os));
String message = textFields[1].getText();
writer.write(message);
writer.newLine();
writer.flush();
}catch (Exception e){
e.printStackTrace();
}
}
}
}
ClientFrame.java
package Research_3;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.net.Socket;
public class ClientFrame extends Frame implements ActionListener {
Label[] labels = new Label[5];
TextField [] textFields = new TextField[5];
Button [] buttons = new Button[5];
TextArea [] textAreas= new TextArea[5];
Panel [] panels = new Panel[5];
Socket Speaker = null;
public ClientFrame(String title) {//构造函数
super(title);
}
public static void main(String[] args) {
ClientFrame f= new ClientFrame("Client");
f.DrawGUI();
}
void DrawGUI() {
labels[0] = new Label("Server IP");
labels[2] = new Label("Say:");
labels[1] = new Label("Server Port:");
textFields[0] = new TextField(35);
textFields[1] = new TextField(35);
textFields[2] = new TextField(90);
buttons[0] = new Button(" Connect ");
buttons[1] = new Button(" Say ");
textAreas[0] =new TextArea(8,8);
panels[0] = new Panel();
panels[1] = new Panel();
for(int i =0;i<=0;++i){
panels[i].add(labels[i]);panels[i].add(textFields[i]);
panels[i].add(labels[1]);panels[i].add(textFields[1]);
panels[i].add(buttons[i]);
}
for(int i =1;i<=1;++i){
panels[i].add(labels[2]);panels[i].add(textFields[2]);panels[i].add(buttons[i]);
}
add(panels[0],"North");
add(panels[1],"South");
add(textAreas[0],"Center");
pack();
setVisible(true);
buttons[0].addActionListener(this);//捆绑事件
buttons[1].addActionListener(this);
}
@Override
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
String tem_IP ;
int tem_Port ;
if (source == buttons[0]) {
textAreas[0].append("Connect to server…" + '\n');
tem_IP = textFields[0].getText();
tem_Port = Integer.parseInt(textFields[1].getText());
try {
Speaker = new Socket(tem_IP.trim(), tem_Port);
} catch (IOException ioException) {
ioException.printStackTrace();
}
Thread ClientLister = new Thread(new Client_Lister(Speaker));
ClientLister.start();//Client输入线程开始
} else {
Thread ClientSpeaker = new Thread(new Client_Speaker(Speaker));
ClientSpeaker.start();//Client线程开始
}
}
class Client_Speaker implements Runnable{//实现Runnable接口
Socket Speaker;
public Client_Speaker(Socket Speaker){
this.Speaker=Speaker;
}
@Override
public void run() {
try {
OutputStream os = Speaker.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter writer = new BufferedWriter(osw);
String message = textFields[2].getText();
writer.write(message);
writer.newLine();
writer.flush();
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
class Client_Lister implements Runnable {
Socket Speaker;
public Client_Lister(Socket Speaker) {
this.Speaker = Speaker;
}
@Override
public void run() {
{
try {
InputStream ios = this.Speaker.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(ios));
String tem = reader.readLine();
while (tem != null) {
textAreas[0].append("Form Server:" + tem + '\n');
tem = reader.readLine();
}
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
样例图片