设计要求:在课本第15章Java网络通信例15.3、15.4的基础上,编写完成以下功能的小型Java聊天室系统。
- 多客户端模式下,实现客户与客户的单独通信,要求信息通过服务器中转。
- 端到端的通信,实现并行模式
- 实现端到端的文件传输。
多客户的单独通信
- 改进思路:在课本例15.3、15.5的基础上,实现多客户的情况下实现客户与客户之间的通信,关键在于服务器端与客户端连接时,获取与客户端一一对应的socket套接字需要在服务器端中存储起来,在客户端收或者发信息时,只要在服务端找到对应的socket即可建立连接,互相传输信息,从而使服务器在聊天过程中起到中转消息的功能。
- 我采用的方法是创建一个ArrayList类的对象SocketRecord,将服务器获取的socket按建立连接的顺序存储起来,使用其add() 和get() 方法存入或获取相应的socket。
- 过程中出现的问题:如下图所示,如客户0与客户1聊天,客户0先给客户1发送消息,此时客户1并不能及时地收到,此时,客户1若在未知的情况下回客户0一条信息,之前客户0发的消息便会同时出现。以上过程服务器端运行过程正常。
- 原因:readline() 方法引起的阻塞问题。以下是客户端收发消息的程序片段。readline()是一个阻塞函数,当没有数据读取时就一直阻塞在那,只有当数据流关闭或者读取到“/r”“/n”“/r/n”才会返回。所以在收消息的客户端中,最初系统没有输入就会一直阻塞在
if((readline=sin.readline())!=null)不会继续执行底下收消息的动作,只有在最初本应收消息的客户端也系统输入之后,就不再阻塞,也就可以接收那条最初本应接收的消息。
- 解决办法:将客户端收发消息的操作分为收消息线程与发消息线程,同时实现要求二实现端到端的并行模式。
并行模式
- 改进思路:主要是对客户端收发消息的功能进行改动,客户端在与服务器通过获取对方socket套接字建立连接之后,就创建两个线程分别收发消息。收发消息分两个线程,实现并行模式使得收发消息互不影响。
- 代码如下
package ChatBox;
import java.io.*;
import java.net.*;
import java.util.*;
/*服务器端*/
public class TalkServer {
public static List<Socket> SocketRecord = new ArrayList<Socket>();
// 用ArrayList记录下不同用户的Socket
static int clientnum = 0;
public static void main(String args[]) throws IOException {
ServerSocket serverSocket = null;
boolean listening = true;
try {
serverSocket = new ServerSocket(4700);
} catch (IOException e) {
System.out.println("Could not listen on port:4700.");
System.exit(-1);
}
while (listening) {
SocketRecord.add(clientnum, serverSocket.accept());
// 将接收到的用户保存到ArrayList相应的位置中
new ServerThread(SocketRecord.get(clientnum), clientnum).start();

本文详细介绍了基于Java的多客户端聊天室系统的设计与实现过程,包括客户端与服务器间的信息中转、并行通信模式及文件传输功能。解决了readline()方法引起的阻塞问题,通过创建收发消息的独立线程,实现了端到端的高效通信。
&spm=1001.2101.3001.5002&articleId=103502529&d=1&t=3&u=b73e81ffe8f241088769667e9308c1dc)
514

被折叠的 条评论
为什么被折叠?



