基于JAVA Socket的网络聊天室
完整内容及代码 github
主要特点
1. 连接mysql
,具有用户的注册和登陆验证功能,端口号:9611
- 存储用户的账户名和密码,以及昵称和
salt
值。 - 密码存储的格式应该是以hash摘要的形式储存,为了避免
hash
冲突,同时储存salt
值,提升安全性。 - 密码的验证方式应该为:
- 用户输入账号密码。
- 客户端基于账号向服务器段请求
salt
值。 - 客户端收到
salt
生成hash digest=hash(password+salt)
; - 将生成的
hash digest
和账号一起到服务器数据库验证。
2. 进入聊天室, 端口号:9806
- 所有传输的信息加密:基于
SSL
- 服务器端:
- 监听阻塞 listen()
- 建立SSLSocket连接后加入SSLSocketList accept() -> SSLSocketList()
- 验证证书及密钥
- 新建接受线程 New ReceiveThread(Socket) -> ReceiveThread.Start()
- 广播消息:ReceiveThread() -> for each(SendThread())
- 客户端:
- 发送SSLSocket请求
- 包括证书和密钥
- 新建两个线程:
- 接收线程: ReceiveThread.start()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26private static class ReceiceThread implements Runnable {
Socket socket;
public ReceiceThread(Socket socket) {
this.socket=socket;
}
public void run() {
try{
InputStream inputStream=socket.getInputStream();
InputStreamReader isr=new InputStreamReader(inputStream);
BufferedReader br =new BufferedReader(isr);
while(true){
String receiveMessage=br.readLine();
if(receiveMessage==null){
socket.shutdownInput();
socket.close();
break;
}
System.out.println(receiveMessage);
}
}
catch (Exception e){
e.printStackTrace();
}
}
} - 发送线程: SendThread.start()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32private static class SendThread implements Runnable {
Socket socket;
public SendThread(Socket socket) {
this.socket=socket;
}
public void run() {
try {
OutputStream outputStream=socket.getOutputStream();
OutputStreamWriter osw=new OutputStreamWriter(outputStream);
PrintWriter pw=new PrintWriter(osw,true);
Scanner scanner=new Scanner(System.in);
String join_text="【"+nickname+" join the chatroom】";
pw.println(join_text);
while(true){
String message=scanner.nextLine();
if(message.equals("\\quit")){//退出聊天程序
String leave_text="【"+nickname+" left the chatroom】";
pw.println(leave_text);
chatFlag=false;
socket.shutdownOutput();
break;
}
String text_temp="【"+nickname+"】"+" : "+message;
pw.println(text_temp);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
- 接收线程: ReceiveThread.start()
- 发送SSLSocket请求