Java Socket BIO

# Java Socket BIO

之前用python2.7做了Socket的快速模型和研發校驗,目前工作進入到產品release 開發階段,所以服務器這方面的技術選型我選擇了java(文檔duo比較完善,第三方包也很多)

### 這裏看過了java的併發,就自己準備封裝了一下java的Socket服務器

#### 需要了解的知識點

[網上扒取得知識點地址]: https://blog.csdn.net/a78270528/article/details/80318571

* TCP

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

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

* JAVA Socket

  所謂socket 通常也稱作”套接字“,用於描述IP地址和端口,是一個通信鏈的句柄。應用程序通常通過”套接字”向網絡發出請求或者應答網絡請求。

  以J2SDK-1.3爲例,Socket和ServerSocket(TCP的服務)類庫位於java.net包中。ServerSocket用於服務器端,Socket是建立網絡連接時使用的。在連接成功時,應用程序兩端都會產生一個Socket實例,操作這個實例,完成所需的會話。對於一個網絡連接來說,套接字是平等的,並沒有差別,不因爲在服務器端或在客戶端而產生不同級別。不管是Socket還是ServerSocket它們的工作都是通過SocketImpl類及其子類完成的。
  **注意:**其中getInputStream和getOutputStream方法均會產生一個IOException,它必須被捕獲,因爲它們返回的流對象,通常都會被另一個流對象使用。

### 封裝的服務器代碼

* 封裝類

  ```java
  package com.server;
  
  
  
  import java.io.IOException;
  import java.io.InputStream;
  import java.io.OutputStream;
  import java.net.*;
  
  public class SocketServer {
      //private String host;
      private int port;
      //private Socket socket;
      ServerSocket server;
      private  int byteLength = 1024;
      public SocketServer(int port)
      {
          //this.host = host;
          this.port = port;
  
      }
      public  void Connect() throws IOException {
          server = new ServerSocket(port);
  
  
      }
      public void Listener()
      {
          while (true)
          {
              try {
                  System.out.println("Start socket wait......");
                  Socket socket = server.accept();
                  InetAddress address = socket.getInetAddress();
                  System.out.println("Socket access to this server address:" + address.getHostAddress() + "_name:" + address.getHostName());
                  InputStream inputStream = socket.getInputStream();
                  byte[] bytes = new byte[byteLength];
                  int len = inputStream.read(bytes);
                  StringBuilder sb = new StringBuilder();
                  if(len > 0){
  
                      sb.append(new String(bytes,0,len));
                  }
                  System.out.println("get data from:" +sb);
                  inputStream.close();
                  socket.close();
  
  
              }catch (Exception e)
              {
                  System.out.println(e.toString());
                  e.printStackTrace();
  
              }
          }
      }
      public void  SendMsg(String data)
      {
  
      }
  
      public  void Close() throws IOException
      {
  
          server.close();
      }
  
  
  
  }
  
  ```

  

* 主函數調用測試

  ```java
  import com.server.SocketServer;
  
  public class Main {
      public static void main(String[] args) {
          SocketServer server =new SocketServer(888);
          try{
              server.Connect();
              server.Listener();
              server.Close();
          }catch (Exception e)
          {
              System.out.println(e.toString());
          }finally {
              return;
          }
  
      }
  }
  
  ```

  

### 測試

開了一個SocketTool2(需要的自己網上下載),創建了多個客戶端去連接服務器,因爲上面的服務器是基於BIO的(阻塞式),所以多個客戶端誰先連接誰先被監聽,知道這個客戶端發送消息後纔會到下個客戶端的監聽

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