2016-9-17 20:50
昨天按照丁振凡老师著述《Java语言实用教程(第2版)》里面的方法,利用Socket基本实现了Java简易多用户聊天程序。服务器端没有一个显示窗体,我感觉这样不方便调试。于是在服务器的main()中利用Frame和TextArea给服务器加上了一个显示窗体。目的是服务器(以下用简写为Ser)工作日志显示。但是一调试,发现第一个链接的客户端(以下简写为Cli)能实时显示,但如果立即链接第二个Cli,则第二个Cli的链接日志没有显示出来。只有在第一个Cli发送一个消息后,第二个Cli的链接日志才会和第一个Cli发送的消息一起显示出来。
除了这个问题外,还存在着Ser只能显示收到的第一条消息(不管是哪个Cli发的),后面不论是哪个Cli的消息都显示不出来了。而且两个Cli的输入结束事件经常不能触发。另外有个小问题:TextArea对象不能在本类外设置显示内容。后来通过参数传递解决了这个问题。还有好些问题,忘记它们的具体现象就不写了。通过不断的调试,到今晚17点半时,只剩下Ser不能显示更多消息的问题。通过认真分析(前面一直试着分析,但没静下来,所以分析了一两句就分心了- _- !)Ser链接的代码(如下)
Socket client = server.accept();
hint = "Client-" + (clientnum + 1) + " has connected." + "\n";
System.out.println("test connect: " + hint);
input.append(hint);
DataInputStream dis = new DataInputStream(client.getInputStream());
DataOutputStream dos = new DataOutputStream(client.getOutputStream());
hint = "Client-" + (clientnum + 1) + " has received." + dis.readUTF() + "\n";
System.out.println("test dis: " + hint);
input.append(hint);
allclient[clientnum] = new Client(clientnum, dis, dos);
allclient[clientnum].start();
clientnum++;
结合对ServerSocket的再次理解,发现:当Cli建立链接后,该部分代码已经被阻塞了,所以不能及时显示Cli发来的消息。只有在相应的Cli线程中去更新显示才行。于是利用参数传递,将main()中的TextArea对象传递到各Cli线程中,利用TextArea的append()实现Ser窗体实时显示收到的Cli消息。
后面又改进了一些其他显示和提示信息。完成的程序代码如下。
---------------------------------------------------------------------------------------------------- 这是服务器的类文件 ----------------------------------------------------------------------------------------------------
import java.awt.Frame;
import java.awt.Panel;
import java.awt.TextArea;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
class Client extends Thread
{
int id;