前言
通过golang实现Tcp的连接与信息传输
本文主要介绍Tcp协议以及如何使用golang来建立一个简单的tcp连接服务,并且实现信息的传输。
首先介绍什么是Tcp协议
Tcp协议是传输层的一个可靠数据传输协议,Tcp协议有以下几个特点:
- 点对点的发送:一个发送方,一个接收方
- 可靠性: 可靠的、按序的字节流
- 流水线机制:TCP拥塞控制和流量控制机制设置滑动窗口尺寸
- 缓存窗口: 发送方/接收方可以进行缓存
- 全双工:同一连接中能够传输双向数据流
- 面向连接:通信双方在发送数据之前必须建立连接,在建立连接之后才能进行数据传输
- 连接状态只在连接的两端中维护,在沿途节点中并不维护状态(端到端)
- TCP连接包括:两台主机上的缓存、连接状态变量、socket等(双方都要维护)
什么是可靠数据传输?
TCP在IP层提供的不可靠服务基础上实现的可靠数据传输服务,基于流水线机制。当有发送端的数据丢失后,接收端不会不予理睬,而是重新会发送给发送方一个信号,请求重新发送该数据报。以此来确保数据的可靠性传输。这里只作简单解释可靠数据传输的特点:
- 累计确认机制:当接收方接收到因为超时重传的帧后,会传输当前累加后的(最大的)ACK序号。
- TCP使用单一重传定时器(也就是SR定时器,只判断ACK的那个帧进行定时处理)
- 触发重传的事件:超时、收到重复ACK
- 渐进式:暂不考虑重复ACK、暂不考虑流量控制、暂不考虑拥塞控制
TCP的快速重传机制
如果TCP通道建立之后,数据在发送过程中丢失。TCP将会触发快速重传机制,下面是快速重传机制的特点:
- 如果发生超时情况,而超时时间间隔过长,则需要等待很长时间。
- 当发送方接收到3个重复的ACK,就触发快速重传机制,直接重新发送这个帧数据。
简单介绍TCP连接的三次握手和四次挥手
三次握手
SYNSYNACKSYNACKACK
四次挥手
FIN_WAIT_1close_waitCLOSE_WAITFIN_WAIT_2LAST_ACKTIME-WAITCLOSEDCLOSED
golang实现简单的tcp连接建立
服务端
主要分为3部分
- 建立tcp监听通道,指定监听端口
net.Listen("tcp", "127.0.0.1:4399") (Listener, error)
- 对通道进行监听
listen.Accept() (Conn, error)
- 关闭监听通道
defer listen.Close()
完整代码
deferdefer
package main import ( "fmt" "net" ) func handle(conn net.Conn) { defer conn.Close() var info [256]byte n, err := conn.Read(info[:]) if err != nil { fmt.Println("conn Read fail ,err = ", err) return } fmt.Println("client send info to server si : ", string(info[:n])) } func main() { // 1. 建立tcp连接监听通道 listen, err := net.Listen("tcp", "127.0.0.1:4399") if err != nil { panic(err) } // 3. 关闭监听通道 defer listen.Close() fmt.Println("server is Listening") for { // 2. 进行通道监听 conn, err := listen.Accept() if err != nil { panic(err) } // 启动一个协程去单独处理该连接 go handle(conn) } }
客户端
客户端和服务端一样,也分为三个部分
- 对指定通道进行连接
net.Dial("tcp", "127.0.0.1:4399") (Conn, error)
- 连接成功后发送数据
msg := "Hi, I am a client" conn.Write([]byte(msg))
- 发送完成后进行关闭连接
defer conn.Close()
完整代码
Writefor
package main import "net" func main() { // 1. 建立访问通道 conn, err := net.Dial("tcp", "127.0.0.1:4399") if err != nil { panic(err) } defer conn.Close() msg := "Hi, I am a client" conn.Write([]byte(msg)) }