您的位置:首页 > 编程语言 > Java开发

Java简易多用户聊天程序项目经历

2016-09-17 20:49 543 查看
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;
TextArea clientDisplay = new TextArea(5,30);
DataOutputStream dos;
DataInputStream dis;

public Client(int id,TextArea display, DataInputStream dis, DataOutputStream dos)
{
this.id = id + 1;
clientDisplay = display;
this.dis = dis;
this.dos = dos;
}

public void run()
{
while(true)
{
try
{
String message = dis.readUTF();
SimpleTalkServer.hint = "Message from Client-" + id + " as following:\n" + message + "\n";

clientDisplay.append(SimpleTalkServer.hint);

int m = SimpleTalkServer.clientnum;

for(int i=0; i<m; i++)
{
SimpleTalkServer.allclient[i].dos.writeUTF(message);
}
}
catch(IOException e)
{}
}
}

}

public class SimpleTalkServer

{
public static Client[] allclient = new Client[20];
public static int clientnum = 0;
public static String hint = "";

public static void main(String[] args)
{
Frame show = new Frame("Server");
Panel p = new Panel();
TextArea input = new TextArea(15, 35);

try {
ServerSocket server = new ServerSocket(8888);
hint = "Server is operating.\n";

input.setText(hint);
p.add(input);
show.add(p);
show.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent w) {
try {
String message = new String("Server closed.\n");

for (int i = 0; i < clientnum; i++) {
SimpleTalkServer.allclient[i].dos.writeUTF(message);
}
server.close();
} catch (IOException e) {
}

w.getWindow().dispose();
System.exit(0);
}
});
show.setSize(300, 300);
show.setVisible(true);

while (true) {
Socket client = server.accept();
hint = "Client-" + (clientnum + 1) + " has connected." + "\n";
input.append(hint);

DataInputStream dis = new DataInputStream(client.getInputStream());
DataOutputStream dos = new DataOutputStream(client.getOutputStream());

allclient[clientnum] = new Client(clientnum, input, dis, dos);
allclient[clientnum].start();
clientnum++;
}

} catch (IOException e) {
}
}

}

-------------------------------------------------------------------------------- 这是客户端的类文件 有一个运行参数:客户端号 ------------------------------------------------------------------------------------

import java.awt.Frame;

import java.awt.Panel;

import java.awt.TextArea;

import java.awt.TextField;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

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.Socket;

class receiveThread extends Thread

{
DataInputStream dis;
TextArea message;

public receiveThread(DataInputStream dis, TextArea mm)
{
this.dis = dis;
message = mm;
this.start();
}

public void run()
{
for(;;)
{
try
{
String str = new String("You have received:\n" + dis.readUTF() + "\n");
message.append(str);
}
catch(IOException e)
{}
}
}

}

public class SimpleTalkClient 

{
public static void main(String[] args) throws IOException
{
Socket client = new Socket("localhost", 8888);
DataInputStream dis = new DataInputStream(client.getInputStream());
final DataOutputStream dos = new DataOutputStream(client.getOutputStream());

Frame show = new Frame("Client-" + args[0]);
Panel p = new Panel();
final TextField input = new TextField(34);
TextArea display = new TextArea(13,35);

p.add(input);
p.add(display);
show.add(p);

new receiveThread(dis, display);

input.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
try
{
String message = new String("Client-" + args[0] + ":" +input.getText());
dos.writeUTF(message);
display.append("You have send:\n" + message + "\n");
}
catch(IOException exception)
{}
}
}
);

show.addWindowListener(new WindowAdapter() 
{
public void windowClosing(WindowEvent w) 
{
try
{
dos.writeUTF("Client-" + args[0] + ":" + "closed.");
client.close();
}
catch(IOException e)
{}

w.getWindow().dispose();
System.exit(0);
}
});

show.repaint();
show.setSize(300, 300);
show.setVisible(true);
}

}

----------------------------------------------------------------------------------------------------------------  代码结束! ----------------------------------------------------------------------------------------------------

后面有时间会持续完善。待完善的问题:用户设定用户名,Cli退出后释放该Cli所占用的位置给新的Cli,给程序加上注释。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息