一、TCP的相关IP
1.1 SeverSocket
这是Socket类,对应到网卡,但是这个类只能给服务器使用.
1.2 Socket
对应到网卡,既可以给服务器使用,又可以给客户端使用.
TCP是面向字节流的,传输的基本单位是字节.
TCP是有连接的,和打电话一样,需要客户端拨号,服务器来听.
服务器的内核会配合客户端这边的工作,来完成连接的建立.
这个连接建立的过程,就相当于电话这边在拨号,另外一边就在响铃.
但是需要等待用户点击了接听,才能进行后续通信.
内核建立的连接不是决定性的,还需要用户程序,把这个程序进行 "接听"/ accept 操作,然后才能进行后续的通信.
accept也是一个可能会产生阻塞的操作,如果当前没有客户端连过来,此时accept就会阻塞.
有一个客户端连过来了,accept一次就能返回一次
有若干个客户端连过来了,accept就需要执行多次.
二、实现TCP回显服务器
2.1 服务器代码
private ServerSocket serverSocket = null;public TcpEchoServer(int port) throws IOException {serverSocket = new ServerSocket(port);}public void start() throws IOException {System.out.println("服务器启动");ExecutorService pool = Executors.newCachedThreadPool();while(true){Socket clientSocket = serverSocket.accept();//Thread t = new Thread(()->{// processConnection(clientsocket);//});//t.start();pool.submit(new Runnable() {@Overridepublic void run() {try {processConnection(clientSocket);} catch (IOException e) {throw new RuntimeException(e);}}});}}private void processConnection(Socket clientSocket) throws IOException {System.out.printf("[%s:%d] 客户端上线!\n",clientSocket.getInetAddress(),clientSocket.getPort());try(InputStream inputStream = clientSocket.getInputStream();OutputStream outputStream = clientSocket.getOutputStream()){while(true){Scanner scanner = new Scanner(inputStream);if(!scanner.hasNext()){System.out.printf("[%s:%d] 客户端下线",clientSocket.getInetAddress(),clientSocket.getPort());break;}String resquest = scanner.next();String response = process(resquest);PrintWriter printWriter = new PrintWriter(outputStream);printWriter.println(response);printWriter.flush();System.out.printf("[%s;%d] req: %s,resp: %s\n",clientSocket.getInetAddress(),clientSocket.getPort(),resquest,response);}} catch (IOException e) {throw new RuntimeException(e);}finally {clientSocket.close();}}public String process(String request){return request;}public static void main(String[] args) throws IOException {TcpEchoServer sever = new TcpEchoServer(9090);sever.start();}
2.2 客户端代码
private Socket socket = null;public TcpEchoClient(String severIp,int severPort) throws IOException {socket = new Socket(severIp,severPort);}public void start(){System.out.println("客户端启动");try(InputStream inputStream =socket.getInputStream();OutputStream outputStream = socket.getOutputStream()) {Scanner scannerConsole = new Scanner(System.in);Scanner scannerNetwoek = new Scanner(inputStream);PrintWriter writer = new PrintWriter(outputStream);while(true){//1.从控制台读取字符System.out.println("->");if(!scannerConsole.hasNext()){break;}String request = scannerConsole.next();//2.把请求发给服务器writer.println(request);writer.flush();//3.从服务器读取响应String response = scannerNetwoek.next();//4.把响应打印出来System.out.println(response);}} catch (IOException e) {throw new RuntimeException(e);}}public static void main(String[] args) throws IOException {TcpEchoClient client = new TcpEchoClient("127.0.0.1",9090);client.start();}