目录

1.实现一个TCP的回显服务

1.Sever Socket API

1.SeverSocket 构造方法

2.Sever Socket方法

 2.Socket API

1.Socket的构造方法

2.Socket 方法

那么怎么实现让服务器可以处理多个客户端呢?

服务端代码:

客户端代码:

1.实现一个TCP的回显服务

1.Sever Socket API

Sever Socket 是创建TCP服务端Socket的API

1.SeverSocket 构造方法

2.Sever Socket方法

 2.Socket API

1.Socket的构造方法

2.Socket 方法

 

但是此服务器只能连接一个客户端,如果需要连接另一个客户端,只能让当前客户端断开连接,再连接另一个客户端

那么怎么实现让服务器可以处理多个客户端呢?

1.可以为每一个客户创建一个新的线程,让请求的处理在单独的子线程中去执行

但是这样如果有一万个客户端需要连接那就要创建一万个线程,会消耗非常大的系统资源,这时我们就可以通过线程池的方式进行优化,只给真正有需要的客户端建立连接

服务端代码:

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

import java.io.PrintWriter;

import java.net.ServerSocket;

import java.net.Socket;

import java.text.MessageFormat;

import java.util.Scanner;

import java.util.concurrent.LinkedBlockingDeque;

import java.util.concurrent.ThreadPoolExecutor;

import java.util.concurrent.TimeUnit;

public class TCPEchoSever {

private ServerSocket server;

public TCPEchoSever(int port) throws IOException {

if (port < 1025 || port > 65535) {

throw new RuntimeException("端口号要在 1025 ~ 65535之间.");

}

//实例化SeverSocket对象

this.server = new ServerSocket(port);

}

public void start() throws IOException {

System.out.println("服务器已启动~~");

ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(3,10,1, TimeUnit.SECONDS,new LinkedBlockingDeque<>(10));

// 循环接收客户端的连接

while (true) {

//接收客户端的数据

Socket clientSocket = server.accept();

// 提交任务到线程池中

poolExecutor.submit(() -> {

try {

processConnections(clientSocket);

} catch (IOException e) {

e.printStackTrace();

}

});

}

}

//处理数据

private void processConnections(Socket clientSocket) throws IOException {

// 打印日志

String clientInfo = MessageFormat.format("[{0}:{1}] 客户端已上线", clientSocket.getInetAddress(),

clientSocket.getPort());

System.out.println(clientInfo);

try (InputStream inputStream = clientSocket.getInputStream();

OutputStream outputStream = clientSocket.getOutputStream()){

while (true) {

Scanner requestScanner = new Scanner(inputStream);

if (!requestScanner.hasNextLine()) {

// 日志

clientInfo = MessageFormat.format("[{0}:{1}] 客户端已下线.", clientSocket.getInetAddress(),

clientSocket.getPort());

System.out.println(clientInfo);

break;

}

String request = requestScanner.nextLine();

String response = process(request);

PrintWriter printWriter = new PrintWriter(outputStream);

printWriter.println(response);

printWriter.flush();

// 打印日志

clientInfo = MessageFormat.format("[{0}:{1}], request: {2}, response: {3}",

clientSocket.getInetAddress(), clientSocket.getPort(), request, response);

System.out.println(clientInfo);

}

} catch (IOException e) {

throw new RuntimeException(e);

} finally {

clientSocket.close();

}

}

private String process(String request) {

System.out.println("收到新消息:" + request);

Scanner scanner = new Scanner(System.in);

String response = scanner.nextLine();

return response;

}

public static void main(String[] args) throws IOException {

TCPEchoSever server = new TCPEchoSever(6666);

server.start();

}

}

 客户端代码:

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

import java.io.PrintWriter;

import java.net.Socket;

import java.util.Scanner;

public class TCPEchoClient {

private Socket clientSocket;

public TCPEchoClient (String serverIp, int serverPort) throws IOException, IOException {

this.clientSocket = new Socket(serverIp, serverPort);

}

public void start() throws IOException {

System.out.println("客户端已启动~~");

// 获取Socket中的输入输出流

try (InputStream inputStream = clientSocket.getInputStream();

OutputStream outputStream = clientSocket.getOutputStream()) {

// 循环处理用户的输入

while (true) {

System.out.println("->");

// 接收用户的输入内容

Scanner requestScanner = new Scanner(System.in);

String request = requestScanner.nextLine();

// 发送用户的请求

PrintWriter printWriter = new PrintWriter(outputStream);

printWriter.println(request);

// 强制刷新缓冲区

printWriter.flush();

// 接收服务器的响应

Scanner responseScanner = new Scanner(inputStream);

// 获取响应数据

String response = responseScanner.nextLine();

// 打印响应内容

System.out.println("接收到服务器的响应:" + response);

}

} catch (IOException e) {

e.printStackTrace();

} finally {

clientSocket.close();

}

}

public static void main(String[] args) throws IOException {

TCPEchoClient client = new TCPEchoClient("127.0.0.1", 6666);

client.start();

}

}

推荐阅读

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。