TCP服務器(以Echo服務器爲例))

TCP服務器

他也涉及到兩個核心的類
ServerSocket
Socket

這裏注意:
UDP協議無連接,類似發微信,直接發就行
TCP協議有連接,類似打電話,要接通才能通話。

這裏依然用回顯服務器模式來體會TCP服務器:

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class TcpEchoServer {
    private ServerSocket serverSocket = null;

    public TcpEchoServer(int port) throws IOException {
        serverSocket = new ServerSocket(port);
    }
    public void start() throws IOException {
        System.out.println("服務器啓動");
        //進入主循環
        while (true) {
           //獲取內核連接
            Socket clientSocket = serverSocket.accept();
            //處理連接
            processConnection(clientSocket);
        }
    }

    private void processConnection(Socket clientSocket) {
        System.out.printf("[%s:%d] 客戶端上線\n",clientSocket.getInetAddress().toString(),
                clientSocket.getPort());
        //獲取clientSocket中的流對象
        try(BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
            BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()))) {
            //客戶端和服務器有時並不是只交互一次
            //這時服務器處理的方式
            //(短連接)1.一個連接客戶端和服務器只交互一次完畢之後就斷開連接
            //(長連接)2.一個連接中客戶端和服務器交互N次,直到滿足一定條件再斷開連接
            //當客戶端斷開連接,循環就結束啦
            //當斷開連接,readLine或者write就會觸發異常
            //此處爲長連接
            while (true) {
                //客戶端發送的數據必須按行
                String request = bufferedReader.readLine();
                String response = process(request);
                bufferedWriter.write(response+"\n");
                System.out.printf("[%s:%d] req: %s;resp %s\n",clientSocket.getInetAddress().toString(),
                        clientSocket.getPort(),request,response);
            }
        } catch (IOException e) {
            System.out.printf("[%s:%d] 客戶端下線\n",clientSocket.getInetAddress().toString(),
                    clientSocket.getPort());
        }
    }

    private String process(String request) {
        return request;
    }

    public static void main(String[] args) throws IOException {
        TcpEchoServer server = new TcpEchoServer(9090);
        server.start();
    }
}

import java.io.*;
import java.net.Socket;
import java.util.Scanner;

public class TcpEchoClient {
    //a.啓動客戶端(和服務器建立連接)
    //b.進入主循環
    //1.讀取用戶輸入內容
    //2.構造請求發送給服務器
    //3.讀取響應
    //4.吧響應顯示在界面
    private Socket socket = null;

    public TcpEchoClient(String serverIp,int serverPort) throws IOException {
        socket = new Socket(serverIp,serverPort);
    }
    public void start() {
        System.out.println("客戶端啓動");
        Scanner scanner = new Scanner(System.in);
        try(BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()))) {
            while (true) {
                System.out.print("->");
                String request = scanner.nextLine();
                if (request.equals("exit")) {
                    break;
                }
                //構造請求併發送
                bufferedWriter.write(request+"\n");
                //讀取響應
                //請求和響應格式不一定相同
                String response = bufferedReader.readLine();
                System.out.println(response);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

在這裏插入圖片描述
在這裏插入圖片描述
此時有一個問題:
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
這裏我們就考慮用線程池來解決這個問題:
在這裏插入圖片描述
節省了頻繁創建和銷燬線程的開銷。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章