1. Demand analysis
- 1-1 or 1-n communication between users
2. Technical Analysis
(1) Client
- The client has two functions: sending messages and receiving messages
- Send message: Use the streaming output of Socket technology, and send it with the printing stream package.
- Access information: use a dedicated thread for reading, and read with a character buffer stream.
(2) Server
- The function of the server: forwarding messages.
- Implement forwarding function:
- 1. Create a service channel ServerSocket
- 2. Establish thread pool ExecutorService->ThreadPoolExecutor
- 3. Waiting for connection
- 4. Add channel objects to the collection
- 5. Add forwarding tasks to the thread pool task queue
- 6. Rewriting of forwarding thread class
- Part 1: Receive message: The character buffer stream reads the received message.
- Part 2: Forwarding information: traverse all channels and get output stream output data.
3. Implement the code
client
class Client1{
public static void main(String[] args) {
try {
//建立通道
Socket sender = new Socket(InetAddress.getLocalHost().getHostAddress(),7777);
new ClientServiceThread(sender).start();
Scanner in = new Scanner(System.in);
if (sender.isConnected()) System.out.println(sender.getRemoteSocketAddress() + " 已连接!");
//输出流
PrintStream outStream = new PrintStream(sender.getOutputStream(),true);
String message;
while(!(message = in.nextLine()).equals("exit")){
outStream.println(message);
}
} catch (IOException e) {
System.out.println("连接已断开");
}
}
}
class Client2{
public static void main(String[] args) {
try {
//建立通道
Socket sender = new Socket(InetAddress.getLocalHost().getHostAddress(),7777);
new ClientServiceThread(sender).start();
Scanner in = new Scanner(System.in);
if (sender.isConnected()) System.out.println(sender.getRemoteSocketAddress() + " 已连接!");
//输出流
PrintStream outStream = new PrintStream(sender.getOutputStream(),true);
String message;
while(!(message = in.nextLine()).equals("exit")){
outStream.println(message);
}
} catch (IOException e) {
System.out.println("连接已断开");
}
}
}
class ClientServiceThread extends Thread{
private Socket socket;
public ClientServiceThread(){
}
public ClientServiceThread(Socket socket){
this.socket = socket;
}
@Override
public void run() {
try {
InputStream in = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String message;
while((message = br.readLine()) != null){
System.out.println(socket.getRemoteSocketAddress() + " " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(System.currentTimeMillis()));
System.out.println(message);
}
} catch (IOException e) {
System.out.println("服务器将您踢出群聊······");
}
}
}
Server
class Server{
public static List<Socket> sockets = new ArrayList<>();
public static void main(String[] args) {
try {
ServerSocket socket = new ServerSocket(7777);
ExecutorService service = new ThreadPoolExecutor(3,5,5, TimeUnit.SECONDS,new LinkedBlockingDeque<>(4),new ThreadPoolExecutor.AbortPolicy());
while(true){
Socket accept = socket.accept();
System.out.println(accept.getRemoteSocketAddress() + "已上线!时间:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(System.currentTimeMillis()));
sockets.add(accept);
service.execute(new ServerThread(accept));
}
} catch (IOException e) {
System.out.println();
}
}
}
class ServerThread implements Runnable{
private Socket socket;
public ServerThread() {
}
public ServerThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
System.out.println(socket.getRemoteSocketAddress() + " 已上线,上线时间:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(System.currentTimeMillis()));
String message;
while((message = reader.readLine())!=null){
//获取信息
System.out.println(socket.getRemoteSocketAddress() + " " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
System.out.println(message);
//使用转发技术,转发其它客户端
sendMessageAll(message);
}
} catch (IOException e) {
System.out.println(socket.getRemoteSocketAddress() + ",下线了,时间:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
Server.sockets.remove(socket);
}
}
private void sendMessageAll(String message) {
for (Socket socket :Server.sockets) {
try {
PrintStream ps = new PrintStream(socket.getOutputStream(),true);
ps.println(message);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
renderings