您的当前位置:首页正文

Java项目开发——Chat即时聊天系统

2022-04-10 来源:易榕旅网


开放实验报告

学院: 计算机电子信息工程学院 专业: 计算机科学与技术 班级: 11级计算机科学与技术本科一班 学号 201101010023 姓名: 邵 帅

一、开放实验项目

Java项目开发—Chat即时聊天系统

二、开放实验时间

2012.11.07—2012.11.28 三、开放实验地点 专业微机室二(B-4009) 四、开放实验目的

综合利用JDK、Eclipse开发环境,实现中小型项目的设计。

本系统采用C/S架构,基于TCP协议实现数据在服务器和客户端之间进行传输,实现聊天信息的存储。

通过“Chat即时聊天系统”的设计过程,深刻了解掌握面向对象程序设计语言Java的核心概念和特性;了解编程技术知识,学会处理异常状况,深入了解Java数据库功能,熟练掌握图形界面的操作技术,掌握Java应用软件的开发环境和开发过程;灵活选择程序设计思想,在编写过程中进一步体会Java与其它编程语言的不同之处,分析出Java的优点和先进之处。同时,使学生能够深入的了解软件项目开发的流程和步骤,掌握每一部分的设计和实现方法,以及充分利用现有的软件工程设计工具来完成项目的设计。

五、开放实验内容 1.概要设计

采用Socket类建立套接字实现客户端与服务端的通讯。 总体数据流图

发送请求 返回回应 客户端数据流图 客户端 服务端 发出连接信号

1

客户端 发送消息 接收并显示消息

服务端数据流图

接受并显示消息

服务端

发送消息 2.设计原理

(1).利用多线程实现多客户机制。服务器总是在指定的端口上监听是否有客户请求,一旦监听到客户请求,服务器就会启动一个专门的服务线程来响应该客户的请求,而服务器本身在启动完线程之后马上又进入监听状态,等待下一个客户的到来。 (2).

服务器在接受客户方的请求后,立即高度一个线程以处理服务器与客 在服务器的程序中首先创建单个Server Socket,并调用accept()来

户方之间的交互,主程序则返回继续监听端口,等待下一个客户的连接请求。前一个线程在完成相应的交互过程后自动退出,连接也将自动关闭。 (3).

等候一个新连接,一旦accept()返回,就取得获得结果的Socket,并用它新建一个线程,令其只为那个特定的客户提供服务。然后再调用accept(),等候下一个新的连接请求。 3.客户端设计

(1)、 数据流图

创建客户端Socket .

发送请求数据,调 接收响应数据 用write() 向服务器发送请求,调用connect() 定义Client类控制客户端,用于实现客户端的接收信息与发送信息等操作

2

(2)、客户端代码 import java.net.*; import java.io.*;

public class Client extends Thread {

Socket skt; // 用于客户端的连接 InetAddress host; // 主机地址 int port; // 端口号 BufferedReader theInputStream; PrintStream theOutputStream; String readin; Face chat;

public Client(String ip, int p, Face chat) { try {

host = InetAddress.getByName(ip); // 获取IP地址 port = p; // 获取端口号 this.chat = chat; } catch (IOException e) { chat.ta.append(e.toString()); } }

public void run() { try {

chat.ta.append(\"准备连线,稍后!\");

skt = new Socket(host, port); // 新建Socket对象 chat.ta.append(\"成功\\n\"); // 缓冲区末尾添加字符串 theInputStream

=

new

BufferedReader(new

InputStreamReader(skt.getInputStream()));

theOutputStream = new PrintStream(skt.getOutputStream()); while (true) {

readin = theInputStream.readLine();

3

chat.ta.append(readin + \"\\n\"); }

} catch (SocketException e) { chat.ta.append(\"未连上!\\n\"); chat.clientBtn.setEnabled(true); chat.serverBtn.setEnabled(true); chat.tfaddress.setEnabled(true); chat.tfport.setEnabled(true); try {

skt.close();

} catch (IOException err) { chat.ta.append(err.toString()); }

} catch (IOException e) { chat.ta.append(e.toString()); } }

public void dataout(String data) { theOutputStream.println(data); } }

4、服务端的设计 (1)、 数据流图

返回相应的数据,调用write() 处理请求数据 接收来自客户端的数据,read() 创建服务端Socket 联编到某一个端口,调用bin() 监听来自客户端的请求,调用listen() 组塞,等待客户端请求,accpt() 定义Server类控制服务端,用于实现服务端的接收信息和发送信息等操作

4

(2)、 服务端代码 import java.awt.*; import java.net.*; import java.io.*;

public class Server extends Thread {

ServerSocket skt; // ServerSocket类监听进入的连接,为每个新的连接产生一个Socket对象

Socket Client[ ]=new Socket[10]; Socket Client1=null; int i = 0; TextArea in; int port,k=0,l=0;

PrintStream theOutputStream; Face chat;

public Server(int port, Face chat) { try {

this.port = port;

skt = new ServerSocket(port); this.chat = chat; } catch (IOException e) { chat.ta.append(e.toString()); } }

public void run() {

chat.ta.append(\"等待连线......\"); while (true) { try {

Client[k] = skt.accept();

//当有客户端连接时就新建一个子线程 if (i < 2) {

5

ServerThread server[] = new ServerThread[10]; server[k]= new ServerThread(Client[k], this.chat, i); l=server.length; server[k].start();

chat.ta.append(\"客户端\"+ Client[k].getInetAddress() + \"已连线\\n\"); //for(int j=0;j= PrintStream(server[k].getClient().getOutputStream()); i = server[k].getI(); k++; } else {

//theOutputStream = new PrintStream(null); }

} catch (SocketException e) { } catch (IOException e) { chat.ta.append(e.toString()); } } }

public void dataout(String data) { //for(int j=0;jtheOutputStream.println(data); } }

class ServerThread extends Thread { ServerSocket skt; Socket Client; TextArea in; int port,i;

BufferedReader theInputStream;

6

new

PrintStream theOutputStream; String readin; Face chat;

public ServerThread(Socket s, Face chat, int i) { this.i = ++i; Client = s; this.chat = chat; }

public int getI() { return this.i; }

public Socket getClient() { return this.Client; }

public void run() { try {

theInputStream

=

new

BufferedReader(new

InputStreamReader(Client.getInputStream()));

theOutputStream = new PrintStream(Client.getOutputStream()); while (true) {

readin = theInputStream.readLine(); chat.ta.append(readin + \"\\n\"); }

} catch (SocketException e) {

chat.ta.append(\"连线中断!\\n\"); // 设置组件可用性 chat.clientBtn.setEnabled(true); chat.serverBtn.setEnabled(true); chat.tfaddress.setEnabled(true); chat.tfport.setEnabled(true); try {

7

i --; skt.close(); Client.close(); } catch (IOException err) { chat.ta.append(err.toString()); }

} catch (IOException e) { chat.ta.append(e.toString()); } }

public void dataout(String data) { theOutputStream.println(data); } }

5、聊天界面的设计

(1)、通过调用Face类对界面进行管理设计,运用Button、TextArea、Label等组件,然后通过actionPerformed触发事件来完成操作。 (2)、界面代码 import java.awt.*; import java.awt.event.*; public class Face extends Frame {

private static final long serialVersionUID = 1L; Button clientBtn, serverBtn; TextArea ta;

TextField tfaddress, tfport, tftype,tfname; Label lbl1,lbl2,lbl3,lbl4; int port; Client client; Server server; boolean iamserver;

8

static Face frm;

public Face() { //实例化组件 clientBtn = new Button(\"客户端\"); serverBtn = new Button(\"服务器\");

ta = new TextArea(\"\ lbl1 = new Label(\"IP地址:\");

tfaddress = new TextField(\"127.0.0.1\ lbl2 = new Label(\"端口:\"); tfport = new TextField(\"8888\"); lbl3 = new Label(\"发送内容:\"); tftype = new TextField(25); lbl4=new Label(\"昵 称:\"); tfname=new TextField(30);

tftype.addKeyListener(new TFListener()); ta.setEditable(false); //向容器中加入以上组件 setLayout(new FlowLayout());

add(lbl1); add(tfaddress);add(lbl2);add(tfport);add(serverBtn); add(clientBtn);add(lbl4);add(tfname);add(ta);add(lbl3);add(tftype);

//设置格式

setLocation(350, 250); //窗口显示在屏幕的位置坐标 setSize(400, 320); //设置窗体大小 setTitle(\"图形界面的聊天程序\"); this.setVisible(true); //设置窗体可见

clientBtn.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { port = Integer.parseInt(tfport.getText());

client = new Client(tfaddress.getText(), port, frm); client.start();

9

tfaddress.setEnabled(false); tfport.setEnabled(false); serverBtn.setEnabled(false); clientBtn.setEnabled(false); tfname.setText(\"客户端\"); }

}); //客户端事件响应

serverBtn.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { port = Integer.parseInt(tfport.getText()); server = new Server(port, frm); server.start(); iamserver = true;

tfaddress.setText(\"成为服务器\"); tfaddress.setEnabled(false); tfport.setEnabled(false); serverBtn.setEnabled(false); clientBtn.setEnabled(false); tfname.setText(\"服务器\"); }

}); //服务器端事件响应

addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); }

}); //窗口事件响应 }

public static void main(String[] args) { //主方法 frm = new Face(); }

10

private class TFListener implements KeyListener { public void keyPressed(KeyEvent e) {

if (e.getKeyCode() == KeyEvent.VK_ENTER) { //按Enter输出显示聊天内容

if (iamserver){ } else{

ta.append(tfname.getText()+\":\\n\" + tftype.getText() + \"\\n\"); client.dataout(tfname.getText()+\":\\n\" +tftype.getText()); tftype.setText(\"\"); } } }

public void keyTyped(KeyEvent e) { }

public void keyReleased(KeyEvent e) { } } }

6、测试与运行结果 服务端的界面

ta.append(tfname.getText()+\":\\n\" + tftype.getText() + \"\\n\"); server.dataout(tfname.getText()+\":\\n\" +tftype.getText());

11

客户端界面

六、开放实验总结

通过这次的开放实验课程,掌握了聊天软件的运行模式,丰富了我对java应用程序编写聊天系统的认识,通过“Chat即时聊天系统”的设计过程,我深刻地认识了在操作过程中,面向对象程序设计语言java的核心概念和特性,以及对异常状况的处理和图形用户界面的操作的优越性,感觉通过此次开放实验课更加让我对学习产生了动力,我希望它不仅仅是一个课程,更是我在学习程序设计中的一次进步,我会通过它去更加努力实现和掌握更多的知识。

12

因篇幅问题不能全部显示,请点此查看更多更全内容