- 一对一单聊的实现:客户端带着发送方ID和接收方ID、信息发送给服务端,服务端从socket池中找出接收方ID进行转发。
- 群发的实现:客户端发送群发消息给服务端,然后服务端从socket池中取出所有正在连接的客户端,然后进行转发
import org.junit.Test;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.HashMap;
import java.util.UUID;
public class socket {
static java.util.Map<String, Socket> socketMap = new HashMap<>();
public static void main(String[] args) throws InterruptedException {
Thread server = new Thread(() -> {
try {
ServerSocket serverSocket = new ServerSocket(6666);
while (true) {
Socket socket = serverSocket.accept();
serverRead(socket);
}
} catch (IOException e) {
System.out.println("报错了");
e.printStackTrace();
}
});
server.join();
server.start();
mySocket b = clientConServer();
mySocket a = clientConServer();
try {
clientSend(a,"你好",b.id);
Thread.sleep(1000);
clientSend(b,"你也好",a.id);
Thread.sleep(1000);
clientSendAll(a,"大家好");
} catch (IOException e) {
e.printStackTrace();
}
Thread.sleep(1000);
disconnect(a);
Thread.sleep(1000);
disconnect(b);
try {
a.socket.close();
b.socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 客户端与服务端建立连接 C
*/
public static mySocket clientConServer() {
mySocket socket = new mySocket();
try {
PrintWriter printWriter = new PrintWriter(socket.socket.getOutputStream());
printWriter.write("connect\n");
printWriter.flush();
printWriter.write(socket.id+"\n");
printWriter.flush();
readThread(socket.socket);
} catch (IOException e) {
e.printStackTrace();
}
return socket;
}
/**
* 服务器监听 S
*/
public static void serverRead(Socket socket) throws IOException {
//开启服务器输入监听线程
SocketInterface socketRead = (Socket socket1) -> {
Thread thread = new Thread() {
public Socket socket = socket1;
String info;
@Override
public void run() {
try {
//获取输入流
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket1.getInputStream()));
while ((info = bufferedReader.readLine()) != null) {
//如果监听到连接指令:connect,则获取socketId,并将此socket连接保存到静态map中
if (info.equals("connect")) {
//获取socketId
String key = bufferedReader.readLine();
//存入在静态Map中
socketMap.put(key, socket);
//回传给客户端,提示已经建立连接
PrintWriter we = new PrintWriter(socket.getOutputStream());
// System.out.println(key);
we.write("客户端" + key + "连接服务器成功\n");
we.flush();
}
//如果监听到连接指令:send,则获取发送客户端socketId:from,接受客户端socketId:to,发送的消息:message
if ("send".equals(info)){
//发送客户端socketId
String from = bufferedReader.readLine();
//接受客户端socketId
String to = bufferedReader.readLine();
//发送
send(from,bufferedReader.readLine(),to);
}
//如果监听到连接指令:sendAll,则群发消息
if ("sendAll".equals(info)){
String from = bufferedReader.readLine();
String message = bufferedReader.readLine();
mass(message,from);
}
//如果监听到连接指令:disconnect,则断开与某个客户端的连接
if ("disconnect".equals(info)){
String from = bufferedReader.readLine();
info = from;
System.out.println(from+"请求断开连接");
socketMap.get(from).getOutputStream().close();
socketMap.get(from).getInputStream().close();
socketMap.get(from).close();
}
// System.out.println(info);
}
} catch (SocketException se) {
System.out.println(info+"已断开");
} catch (IOException e) {
e.printStackTrace();
}
}
};
thread.start();
};
socketRead.read(socket);
}
/**
* 客户端接受信息 C
*
* @param socket
*/
public static void readThread(Socket socket) {
//开启客户端输入监听线程
SocketInterface socketRead = (Socket socket1) -> {
Thread thread = new Thread() {
public Socket socket = socket1;
public String info = null;
@Override
public void run() {
try {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket1.getInputStream()));
while ((info = bufferedReader.readLine()) != null) {
System.out.println(info);
}
} catch (SocketException se) {
System.out.println("socket关闭");
} catch (IOException e) {
e.printStackTrace();
}
}
};
thread.start();
};
socketRead.read(socket);
}
/**
* 服务器转发群发消息 S
*
* @param message
*/
public static void mass(String message, String fromUUID) {
//遍历所有已连接服务器的socket
socketMap.forEach((s, socket) -> {
if (!socket.isClosed()) {
try {
// 发送信息
PrintWriter printWriter = new PrintWriter(socket.getOutputStream());
printWriter.write( s+"收到来自<---"+fromUUID + "的群发消息:" + message + "\n");
printWriter.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
/**
* 客户端发送给客户端 C
* @param a
* @param message
* @param to
* @throws IOException
*/
public static void clientSend(mySocket a,String message,String to) throws IOException {
PrintWriter printWriter = new PrintWriter(a.socket.getOutputStream());
printWriter.write("send\n");
printWriter.flush();
printWriter.write(a.id+"\n");
printWriter.flush();
printWriter.write(to+"\n");
printWriter.flush();
printWriter.write(message+"\n");
printWriter.flush();
}
/**
* 客户端群发消息 C
*
* @param a
* @param message
* @throws IOException
*/
public static void clientSendAll(mySocket a,String message) throws IOException {
PrintWriter printWriter = new PrintWriter(a.socket.getOutputStream());
printWriter.write("sendAll\n");
printWriter.flush();
printWriter.write(a.id+"\n");
printWriter.flush();
printWriter.write(message+"\n");
printWriter.flush();
}
/**
* 服务器转发 S
* @param from
* @param message
* @param to
* @throws IOException
*/
public static void send(String from,String message,String to) throws IOException {
//从socket池中获取接受客户端socket,并写入信息
PrintWriter printWriter = new PrintWriter(socketMap.get(to).getOutputStream());
printWriter.write(to+"\n");
printWriter.flush();
printWriter.write(from+"发送给-->"+to+":"+message+"\n");
printWriter.flush();
}
/**
*
* 断开连接 C
*/
static void disconnect(mySocket mySocket){
try {
PrintWriter printWriter = new PrintWriter(mySocket.socket.getOutputStream());
printWriter.write("disconnect\n");
printWriter.flush();
printWriter.write(mySocket.id+"\n");
printWriter.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
static class mySocket {
public String id;
public Socket socket;
mySocket() {
this.id = UUID.randomUUID().toString();
try {
this.socket = new Socket("192.168.157.1", 6666);
} catch (IOException e) {
e.printStackTrace();
}
}
}
接口类
import java.net.Socket;
public interface SocketInterface {
/**
* 开启监听
*/
void read(Socket socket);
}