java在线聊天系统_手把手教你写一个Java在线聊天系统

手把手教你写一个Java在线聊天系统

标签: Java Toy_Programm Thread Swing/AWT

东软2016暑假实训内容,之前写过,这次想按自己思路独立写一遍。

1. Let’s Chat V0.1

创建一个窗口,起一个客户端ChatClient.java

extends Frame

设置客户端标题,可见性,位置,大小,窗口关闭形式 private void launchFrame() {

this.setTitle("Let's Chat");

this.setBounds(100, 100, 400, 300);

//这样写,可以在关闭窗口时,做资源回收的当作

this.addWindowListener(new WindowAdapter(){

public void windowClosing(WindowEvent e) {

System.exit(0);

}

});

this.setVisible(true);

}

2. Let’s Chat V0.2

添加文本域

TextField

TextArea

设置TextField在BorderLayout.SOUTH

设置TextArea在BorderLayout.NORTH

当我尝试使用JTextField和JTextArea达不到TextField和TextArea的效果,所以我使用后者。

this.pack();//消除组件之间的间隙

3. Let’s Chat V0.3

往TextField里输入,输出到TextArea里

这里我们想当按下ENTER时达到这种效果,采用事件与监听器

为TextField添加一个监听器

常规写法,或者我们可以单独写一个类,如果方法里,代码太长,就应该写一个内部类 tf.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {

ta.setText(tf.getText().trim());

tf.setText("");

}

});

这里的接口ActionListener只有一个方法,就是函数式接口,所以这里我们可以采用Lambda编程

tf.addActionListener((e)->{

ta.setText(tf.getText().trim());

tf.setText("");

});

4. Let’s Chat V0.4

起一个服务器端ChatServer.java,基于TCP的

服务器端

注意捕捉异常

private ServerSocket ss = null;

private Socket s = null;

ss = new ServerSocket(9600);

s = ss.accept();

- 服务器重复打开,占用同一端口

- IOException

开启服务器,开启客户端,两者能连上

客户端

注意捕捉异常

private Socket s = null;

s = new Socket("127.0.0.1",9600);

- 服务器未打开,先打开客户端

- IOException

5. Let’s Chat V0.5

客户端输入一句话,服务端能收到

服务器端 private DataInputStream dis = null;

dis = new DataInputStream(s.getInputStream());

String str = dis.readUTF();

客户端 private DataOutputStream dos = null;

dos = new DataOutputStream(s.getOutputStream());

dos.writeUTF(str);

dos.flush();

6. Let’s Chat V0.6

客户端不断输入一句话,服务器能收到

使用while(true) {} while(true) {

dis = new DataInputStream(s.getInputStream());

String str = dis.readUTF();

System.out.println(str);

}

我们注意到关闭客户端会报一些异常,这是因为我们没有在关掉窗口时对资源进行关闭回收

关闭客户端,服务器端SocketException

关闭服务器,一旦尝试输入,服务器端SocketException

这里我们对其作简单处理,即在出现异常的地方,捕捉它,输出一个提示信息,然后退出程序

catch (SocketException se) {

System.out.println(“A Server quit…”);

System.exit(0);

}

7. Let’s Chat V0.7

多个客户端能够连上服务器端

采用两个死循环,外层不断侦听并接受到此套接字的连接,内层不断读取字符。实际运行我们发现无论如何都只能连接一个客户端。这是应为readUTF()是一个阻塞性函数,所以main()会一直阻塞在这里。

while(true) {

s = ss.accept();

while(true) {

dis = new DataInputStream(s.getInputStream());

String str = dis.readUTF();

System.out.println(str);

}

}

思路:把内层循环里读取字符的动作封装成一个线程(这意味着程序要做很大的更改)。

8. Let’s Chat V0.8

服务器端能够把信息发送给每一个客户端,并且客户端能接收

客户端能接收

起一个线程,不断地读取字符 public void run() {

try {

while(conned) {

dis = new DataInputStream(s.getInputStream());

String str = dis.readUTF();

ta.setText(ta.getText()+str+"\n");

}

} catch (IOException e) {

e.printStackTrace();

}

}

服务器端能够把信息发送给每一个客户端

为了达到这个目的,我们需要把每一个线程的信息都保存,于是我们想到用泛型ArrayList来实现。

所以服务器端需要做的就是,在每读取到字符时,都给每个客户端发一遍。 for(int i=0 ; i

9. Let’s Chat V0.9

做最后的进一步完善

当关闭一个客户端时,从ArrayList里remove(this)

注:移除了,但是,还是会报一些异常,我做捕捉,但是并未处理。

设置窗口不可改大小

文本TextArea不可编辑

添加发送信息时的时间

添加了一些注释

后期添加功能

监听线程

数据端口和控制端口,不同端口号

好的处理关闭方法

告诉服务器端客服端要关闭了,服务器端做资源关闭处理

客户端信息

给每一个客户端一个名字,单独聊天(私聊),群聊

传文件

传表情,文件之类的

注:github源码

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值