TCP Protocol 介紹

TCP 通訊需要做三次的Hand Shaking才能開始通訊,主要的原因就是為了防止重複初始化或是錯誤的連結。如果通信雙方的通信次數只有兩次,那麼發送方一旦發出建立連接的請求之後它就沒有辦法撤回這一次請求,如果在網路狀況複雜或者較差的網路中,發送方連續發送多次建立連接的請求,如果 TCP 建立連接只能通信兩次,那麼接收方只能選擇接受或者拒絕發送方發起的請求,它並不清楚這一次請求是不是由於網路擁堵而早早過期的連接。
所以,TCP 選擇使用三次握手來建立連接並在連接引入了 RST 這一控制消息,接收方當收到請求時會將發送方發來的 SEQ+1 發送回接收方,這時由發送方來判斷當前連接是否是歷史連接:

  • 如果當前連接是歷史連接,即 SEQ 過期或者超時,那麼發送方就會直接發送 RST 控制消息中止這一次連接
  • 如果當前連接不是歷史連接,那麼發送方就會發送 ACK 控制消息,通信雙方就會成功建立連接;

使用三次握手和 RST 控制消息將是否建立連接的最終控制權交給了發送方,因為只有發送方有足夠的上下文來判斷當前連接是否是錯誤的或者過期的,這也是 TCP 使用三次握手建立連接的最主要原因。

Client side 程式

// init
   tcpAddr, err := net.ResolveTCPAddr(resolver, serverAddr)
   if err != nil {
        // handle error
   }
   conn, err := net.DialTCP(network, nil, tcpAddr)
   if err != nil {
           // handle error
   }

   // send message
    _, err = conn.Write({message})
   if err != nil {
        // handle error
   }

   // receive message
   var buf [{buffSize}]byte
   _, err := conn.Read(buf[0:])
   if err != nil {
        // handle error
   }

Server side

// init
   tcpAddr, err := net.ResolveTCPAddr(resolver, serverAddr)
       if err != nil {
           // handle error
       }
   
       listener, err := net.ListenTCP("tcp", tcpAddr)
    if err != nil {
        // handle error
    }
    
    // listen for an incoming connection
    conn, err := listener.Accept()
    if err != nil {
        // handle error
    }
    
    // send message
    if _, err := conn.Write({message}); err != nil {
        // handle error
    }    
    // receive message
    buf := make([]byte, 512)
    n, err := conn.Read(buf[0:])
    if err != nil {
        // handle error
    }

參考資訊