TCP粘包拆包一

1、示例java

    互聯網的發展使得設備之間的網絡通信必不可少,一般用的最多的傳輸層協議就是TCP協議。有以下場景:
    有A、B兩個節點,A、B創建TCP鏈接後,A對B說了一百句話。數據庫

    一、客戶端程序編程

public class SocketClient {
	public static void main(String[] args) throws Exception {
		Socket socket = new Socket("127.0.0.1", 8088);
		OutputStream os = socket.getOutputStream();
		PrintWriter pw = new PrintWriter(os);
		for (int i = 0; i < 100; i++) {
			os.write("A".getBytes());
		}
		pw.flush();
		pw.close();
		os.close();
		socket.close();
	}
}

   二、服務端程序網絡

public class SocketServer {
	public static void main(String[] args) throws Exception {
		ServerSocket serverSocket = new ServerSocket(8088);
		while (true) {
			Socket socket = serverSocket.accept();
			InputStream is = socket.getInputStream();
			int i = 0;
			byte[] b = new byte[10];
			while (is.read(b) != -1) {
				i++;
				System.out.println(new String(b));
				b = new byte[10];
			}
			System.out.println("總數讀取次數" + i);
			is.close();
			socket.close();
		}
	}

}

三、運行結果
     總讀取次數老是少於100

2、問題
    上面所述問題是很常見的場景,創建起一個長鏈接進行交互,列如RPC、NIO編程等等。
     咱們但願的結果是,一次交互一次讀寫,上面實例運行結果少於100次,說明有些數據庫包被打包在一塊兒發送,這就引出了今天的話題,TCP粘包拆包。

3、TCP粘包拆包
    TCP協議是「流」協議,沒有邊界,TCP是傳輸層協議,它並不知道應用層業務數據的真正含義,它會根據TCP緩衝區的具體大小來進行包的劃分,一個完整的包可能會被拆分紅多個包來傳輸,也可能多個包會被合併層一個大數據包來傳輸,這就是粘包和拆包。

4、可能出現的狀況
    假設Client端向Server端發送A、B兩個數據包,可能出現如下狀況
    一、服務端接收到A、B兩個獨立的數據包,沒有拆包和粘包,這種狀況是咱們大多數場景下但願的;
    二、服務端一次性收到了AB兩個包,A、B兩包被粘在一塊兒發送過來;
    三、A數據包被拆分紅A一、A2,服務端先收到A1包,後收到A2和B的合包,這就發生了拆包和粘包兩種狀況;
    四、狀況最糟糕的是A、B兩包被屢次拆分,發送到服務端。

    大多數狀況下,咱們但願一次交互,能拿到交互中傳遞的完整信息,那麼有哪些解決方案解決TCP傳輸過程當中的拆包與粘包問題呢?請關注《TCP粘包拆包二》。
 socket

快樂源於分享。大數據

   此博客乃做者原創, 轉載請註明出處  code

相關文章
相關標籤/搜索