TCP状态转换图:
主动发起连接请求端: CLOSED —— 完成三次握手 —— ESTABLISEHED(数据通信状态)—— Dial()函数返回
被动发起连接请求端: CLOSED —— 调用Accept()函数 —— LISTEN —— 完成三次握手 —— ESTABLISEHED (数据通信状态)—— Accept()函数返回
数据传递期间 —— ESTABLISEHED (数据通信状态)
主动关闭连接请求端:
ESTABLISEHED —— FIN_WAIT_2 (半关闭)—— TIME_WAIT —— 2MSL —— 确认最后一个ACK被对端成功接收。—— CLOSE
半关闭、TIME_WAIT、2MSL ——只会出现在 “主动关闭连接请求端”
被动关闭连接请求端:ESTABLISEHED —— CLOSE
查看状态命令:
windows:netstat -an | findstr 8001(端口号)
Linux: netstat -apn | grep 8001
TCP-CS并发服务器:
1. 创建 监听套接字 listener := net.Listen("tcp", 服务器的IP+port)
2. defer listener.Close()
3. for 循环 阻塞监听 客户端连接事件 conn := listener.Accept()
4. 创建 go程 对应每一个 客户端进行数据通信 go HandlerConnet()
5. 实现 HandlerConnet(conn net.Conn)
1) defer conn.Close()
2) 获取成功连接的客户端 Addr conn.RemoteAddr()
3) for 循环 读取 客户端发送数据 conn.Read(buf)
4) 处理数据 小写 —— 大写 strings.ToUpper()
5)回写转化后的数据 conn.Write(buf[:n])
func HandlerConnect(conn net.Conn) {
defer conn.Close()
addr := conn.RemoteAddr()
fmt.Println(addr, "客户端成功连接!")
buf := make([]byte, 4096)
for {
n, err := conn.Read(buf)
if "exit\n" == string(buf[:n]) || "exit\r\n" == string(buf[:n]) {
fmt.Println("服务器接收的客户端退出请求,服务器关闭")
return
}
if n == 0 {
fmt.Println("服务器检测到客户端已关闭,断开连接!!!")
return
}
if err != nil {
fmt.Println("conn.Read err:", err)
return
}
fmt.Println("服务器读到数据:", string(buf[:n]))
conn.Write([]byte(strings.ToUpper(string(buf[:n]))))
}
}
func main() {
listener, err := net.Listen("tcp", "192.168.15.78:8001")
if err != nil {
fmt.Println("net.Listen err:", err)
return
}
defer listener.Close()
for {
fmt.Println("服务器等待客户端连接...")
conn, err := listener.Accept()
if err != nil {
fmt.Println("listener.Accept err:", err)
return
}
go HandlerConnect(conn)
}
}
TCP-CS并发客户端:
1. 匿名 go 程 , 获取 键盘输入, 写给服务器
2. for 循环读取服务器回发数据
发送数据时,默认在结尾自带‘ \r\n ’
func main() {
conn, err := net.Dial("tcp", "192.168.15.78:8001")
if err != nil {
fmt.Println("net.Dial err:", err)
return
}
defer conn.Close()
go func() {
str := make([]byte, 4096)
for {
n, err := os.Stdin.Read(str)
if err != nil {
fmt.Println("os.Stdin.Read err:", err)
continue
}
conn.Write(str[:n])
}
}()
buf := make([]byte, 4096)
for {
n, err := conn.Read(buf)
if n == 0 {
fmt.Println("检查到服务器关闭,客户端也关闭")
return
}
if err != nil {
fmt.Println("conn.Read err:", err)
return
}
fmt.Println("客户端读到服务器回发:", string(buf[:n]))
}
}