Java Socket TCP

TCP簡介

TCP(Transmission Control Protocol 傳輸控制協議)是一種面向連接的、可靠的、基於字節流的傳輸層通信協議,由IETF的RFC 793定義。在簡化的計算機網絡OSI模型中,它完成第四層傳輸層所指定的功能,用戶數據報協議(UDP)是同一層內[1] 另一個重要的傳輸協議。在因特網協議族(Internet protocol suite)中,TCP層是位於IP層之上,應用層之下的中間層。不同主機的應用層之間經常需要可靠的、像管道一樣的連接,但是IP層不提供這樣的流機制,而是提供不可靠的包交換。 [1]

應用層向TCP層發送用於網間傳輸的、用8位字節表示的數據流,然後TCP把數據流分區成適當長度的報文段(通常受該計算機連接的網絡的數據鏈路層的最大傳輸單元( [1] MTU)的限制)。之後TCP把結果包傳給IP層,由它來通過網絡將包傳送給接收端實體 [1] 的TCP層。TCP爲了保證不發生丟包,就給每個包一個序號,同時序號也保證了傳送到接收端實體的包的按序接收。然後接收端實體對已成功收到的包發回一個相應的確認(ACK);如果發送端實體在合理的往返時延(RTT)內未收到確認,那麼對應的數據包就被假設爲已丟失將會被進行重傳。TCP用一個校驗和函數來檢驗數據是否有錯誤;在發送和接收時都要計算校驗和

下面爲大家介紹Java Socket TCP協議數據傳輸的用法

涉及到的java類

  • ServerSocket (服務器)
  • Sokcet (客戶端)
  • InetSocketAddress (IP、端口信息)

ServerSocket(socket服務端)

1.創建ServerSocket

ServerSocket serverSocket = new ServerSocket(2000);

這樣就創建了一個ServerSocket 監聽給2000端口發送的數據

2.監聽客戶端連接

通過調用serverSocket的accept方法接受客戶端的請求

Socket socket = serverSocket.accept();

accpet方法是一個阻塞方法 只有接到客戶端的連接後,纔會向下繼續執行

返回的對象就是客戶端socket對象(包含客戶端ip,端口port,終端名稱等)

####3.獲取客戶端發送的數據

InputStream is=socket.getInputStream();
byte[] buffer=new byte[1024];
//rLen代表讀取到字節數量
int rLen=is.read(buffer);

socket.getInputStream()方法拿到客戶端的輸入流 用來讀取客戶端發送的數據

創建一個1024個字節的緩衝區用於讀取客戶端發送字節數據,這裏一般需要循環讀取直到rLen的值爲0 說明數據讀取完畢(ps 可以創建一個字節集合存放讀取的的數據)

4.發送數據給客戶端

OutputStream os=socket.getOutputStream();
String responseContent="respones 數據";
//將字符數據轉換成字節數組
byte[] buffer=responseContent.getBytes();
//發送到客戶端
os.write(buffer);

socket.getOutputStream()獲取客戶端的輸出流,用來發送數據給客戶端

下面是完整代碼實現

public static void main(String[] args) throws IOException {
    //創建一個server socket
    ServerSocket serverSocket = new ServerSocket(2000);
    System.out.println("服務器準備就緒..");
    System.out.println("服務器信息:IP " + serverSocket.getInetAddress() + " P " + serverSocket.getLocalPort());
    //開啓監聽客戶端請求
    for (; ; ) {
        Socket socket = serverSocket.accept();
        ClientHandler clientHandler = new ClientHandler(socket);
        clientHandler.start();
    }
}

public static class ClientHandler extends Thread {
    private final Socket socket;

    public ClientHandler(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        super.run();
        System.out.println("新客戶端連接:IP " + socket.getInetAddress() + " P " + socket.getPort());
        try {
            PrintStream printStream = new PrintStream(socket.getOutputStream());
            InputStream inputStream = socket.getInputStream();
            BufferedReader socketInput = new BufferedReader(new InputStreamReader(inputStream));
            while (true) {
                String receiveMsg = socketInput.readLine();
                if ("bye".equals(receiveMsg)) {
                    printStream.println("bye");
                    break;
                } else {
                    System.out.println(receiveMsg);
                    printStream.println("server 說:" + receiveMsg.length());
                }
            }
            socketInput.close();
            printStream.close();

        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("連接異常斷開");
        } finally {
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        System.out.println("客戶端斷開連接:IP " + socket.getInetAddress() + " P " + socket.getPort());
    }
}

Socket客戶端

1.創建並連接SocketServer

//創建一個socket客戶端對象
Socket socket = new Socket();
//連接服務器 ip 端口port 2000 超時時間3000毫米
socket.connect(new InetSocketAddress(Inet4Address.getLocalHost(), 2000),3000);

2.獲取輸出流用於發送數據

OutputStream outputStream = socket.getOutputStream();
String requestContent="request 數據";
//將字符數據轉換成字節數組
byte[] buffer=requestContent.getBytes();
//發送到服務器
os.write(buffer);

3.獲取輸入流用於讀取server發送的數據

InputStream is=socket.getInputStream();
byte[] buffer=new byte[1024];
//rLen代表讀取到字節數量
int rLen=is.read(buffer);

拿到server的數據進行處理

下面是客戶端的完整代碼實現

public static void main(String[] args) throws IOException {
    Socket socket = new Socket();
    socket.connect(new InetSocketAddress(Inet4Address.getLocalHost(), 2000),3000);
    System.out.println("發起服務器連接...");
    System.out.println("客戶端信息:IP " + socket.getLocalAddress() + " P " + socket.getLocalPort());
    System.out.println("服務器信息:IP " + socket.getInetAddress() + " P " + socket.getPort());
    try {
        send(socket);
    } catch (Exception e) {
        e.printStackTrace();
        System.out.println("異常關閉");
    } finally {
        socket.close();
        System.out.println("客戶端已退出");
    }
}

public static void send(Socket socket) throws IOException {
    InputStream in = System.in;
    //鍵盤輸入流
    BufferedReader input = new BufferedReader(new InputStreamReader(in));
    InputStream socketInputStream = socket.getInputStream();
    BufferedReader socketBufferedReader = new BufferedReader(new InputStreamReader(socketInputStream));
    OutputStream outputStream = socket.getOutputStream();
    PrintStream printStream = new PrintStream(outputStream);
    while (true) {
        String request = input.readLine();
        printStream.println(request);
        String response = socketBufferedReader.readLine();
        if ("bye".equals(response)) {
            break;
        } else {
            System.out.println(response);
        }
    }
    input.close();
    socketBufferedReader.close();
    printStream.close();
}

這就是tcp Java socket api的基本使用

下篇準備給大家講下UDP相關知識以及用法

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