1.单线程聊天室
聊天室是客户端与服务器组成,下图可以清楚理解的它们之间的关系:
1.1单线程服务器
1.11.创建服务器(建立ServerSocket)
1.12.等待客户端连接
1.13.接收数据与发送数据
1.14.服务器接受客户端发送的信息
1.15.从服务器发送信息到客户端
注意:服务端先接受信息时,客户端应该是先发送信息,更不能同时发送与接收,因为是单线程
package com.bittech.chartrom.clinet.single;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Scanner;
public class SingleClinet {
public static void main(String[] args) {
//客户端
String host="127.0.0.1";
int port=6080;
try {
//1.创建客户端Socket和服务器建立连接
final Socket socket=new Socket(host,port);
//2.客户端进行接收和发送信息
// 2.1接收数据
InputStream inputStream=socket.getInputStream();
Scanner scanner=new Scanner(inputStream);
String message=scanner.next();
System.out.println("从服务器接受的信息"+":"+message);
//2.2发送数据
OutputStream outputStream=socket.getOutputStream();
PrintStream printStream=new PrintStream(outputStream);
printStream.print("服务器我来了。。。");
printStream.flush();
} catch (IOException e) {
e.printStackTrace( );
}
}
}
1.2.单线程客户端
1.21.创建客户端
1.22.连接服务器端
1.23.发送数据与接受数据
1.24由客户端向服务器发送数据
1.25客户端接受服务器发送的数据
package com.bittech.chartrom.clinet.single;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Scanner;
public class SingleClinet {
public static void main(String[] args) {
//客户端
String host="127.0.0.1";
int port=6080;
try {
//1.创建客户端Socket和服务器建立连接
final Socket socket=new Socket(host,port);
//2.客户端进行接收和发送信息
// 2.1接收数据
InputStream inputStream=socket.getInputStream();
Scanner scanner=new Scanner(inputStream);
String message=scanner.next();
System.out.println("从服务器接受的信息"+":"+message);
//2.2发送数据
OutputStream outputStream=socket.getOutputStream();
PrintStream printStream=new PrintStream(outputStream);
printStream.print("服务器我来了。。。");
printStream.flush();
} catch (IOException e) {
e.printStackTrace( );
}
}
}
2.多线程聊天室
2.1项目简介
在单线程聊天室的基础上进行扩展,多线程聊天系统是由多个客户端与一个服务器组成,多个用户可以在同一局域网下进行聊天,项目实现了以下功能。
- 注册
- 私聊
- 群聊
- 下线
- 显示当前在线好友
类设计如图:
2.2项目流程
客户端通过对应端口号,和IP地址与服务器端建立连接后,进行注册,然后通过输入输出流,进行通信。服务器端收到信息后,进行解析,判断客户端的需求(私聊,群聊,下线等),从而进行相应的处理。因为采取多线程的方式,服务器端,线程比较多,采取线程池的方式进行处理。每个客户端仅需要一个发送和一个接受线程,而且也不牵扯什么资源共享的问题,直接继承Thread类来实现多线程。用一个ConcurrentHashMap存储当前在线用户信息。key–Socket,Value–String(用户名)
2.3遇到的问题及解决方案
问题一:客户端收不到消息(1.服务器没发过来? 2.客户端读不来?)
- 没有使用println。
- 使用了仍然没有发出去,没有flush。
问题二:流采用自动关闭的方式
- 流关闭的太快了,导致Socket中断。最终只能采取手动关闭。
问题三:IP地址的验证
- 相对来说比较简单,字符串拆分加判断就OK了。
2.4知识体系
- Java集合框架
- 多线程
- Java网络编程
- JavaIO 其它知识
项目源码:多线程聊天室
2.5项目不足之处
- 应该使用数据库代替文件存放信息
- 项目功能点不足,应继续扩展登录,清屏,下线后发送信息继续保存至下一次登录
- 可以使用Web知识,开发页面聊天替代命令行。