连接
tcp建立连接通过三次握手,释放需要四次挥手
TCP本身没有长短之分,这完全却决于我们怎么用它
- 短链接:每次通信时,创建Socket,一次通信结束,调用close关闭,这样使用好处就是管理起来比较简单
- 长连接:每次通信完毕之后不端来连接,这样就可以做到复用,省去了创建连接的耗时
优点
- 可以省去较多的TCP建立连接和关闭操作,节省资源,时间
- 减少后续请求的响应时间
问题
client和server如果长时间不关闭的话,会存在随着客户端的越来越多,服务端早晚会扛不住
解决
在服务端连接客户端时使用心跳函数来检查该客户端是否又通信交流,设定持续时间,如果在规定时间内为有通信,服务端断开连接,当收到信息时重新计时
select {
case msg := <-readerChannel:
fmt.Println(conn.RemoteAddr().String(), "get message, keeping heartbeating...")
conn.SetDeadline(time.Now().Add(time.Duration(timeout) * time.Second))
fmt.Println("收到的信息:", msg)
// istrue = false
break
case <-time.After(time.Second * 5):
istrue = false
fmt.Println("It's really weird to get Nothing!!!")
conn.Close()
}
服务端开启服务
tcpAddr, _ = net.ResolveTCPAddr("tcp", "0.0.0.0:8080")
tcpListener, _ := net.ListenTCP("tcp", tcpAddr)
defer tcpListener.Close()
for {
tcpConn, err := tcpListener.AcceptTCP()//发生阻塞等待连接
if err != nil {
continue
}
fmt.Println("A client connected : ", tcpConn.RemoteAddr().String())
go tcpPipe(tcpConn)
}
服务端接收信息
lion := make(chan string, 1)
go HeartBeating(conn, lion, 5)//心跳函数
reader := bufio.NewReader(conn)
for {
message, err := reader.ReadString('\n')
if err != nil {
return
}
fmt.Println(message)
lion <- message
}
客户端连接
tcpAddr, _ = net.ResolveTCPAddr("tcp", "0.0.0.0:8080")
conn, _ := net.DialTCP("tcp", nil, tcpAddr)
defer conn.Close()
fmt.Println("connected!")
go onMessageRecived(conn)
向客户端发送信息
用户可在终端中写入信息发个客户端
reader := bufio.NewReader(os.Stdin)
for {
msg, err := reader.ReadString('\n')
if err != nil {
quitSemaphore <- true
break
}
time.Sleep(time.Second)
b := []byte(msg)
conn.Write(b)
}