服务端 server/main.go
package main
import (
"fmt"
"log"
"net"
)
var clients = make(map[net.Conn]bool)
func handleConnection(conn net.Conn) {
defer func() {
if _, ok := clients[conn]; ok {
delete(clients, conn)
}
conn.Close()
}()
clients[conn] = true
for {
p := make([]byte, 1024)
n, err := conn.Read(p)
if err != nil {
log.Println("conn.Read err:", err)
return
}
fmt.Println(conn.RemoteAddr().String(), string(p[:n]))
_, err = conn.Write(p[:n])
if err != nil {
log.Println("conn.Write err:", err)
return
}
}
}
func main() {
ln, err := net.Listen("tcp", ":8080")
if err != nil {
log.Fatal("net.Listen err:", err)
}
defer ln.Close()
for {
conn, err := ln.Accept()
if err != nil {
log.Println("ln.Accept err:", err)
continue
}
go handleConnection(conn)
}
}
客户端 client/main.go
package main
import (
"fmt"
"log"
"net"
"time"
)
func main() {
conn, err := net.Dial("tcp", "127.0.0.1:8080")
if err != nil {
log.Fatal("net.Dial err:", err)
}
defer conn.Close()
go func() {
for {
p := make([]byte, 1024)
n, err := conn.Read(p)
if err != nil {
log.Println("conn.Read err:", err)
return
}
fmt.Println("收到消息:", string(p[:n]))
}
}()
for {
fmt.Print("请输入:")
var message string
fmt.Scanln(&message)
_, err := conn.Write([]byte(message))
if err != nil {
log.Println("conn.Write err:", err)
return
}
time.Sleep(250 * time.Millisecond)
}
}
封包拆包
// math.MaxUint32
// binary.BigEndian.PutUint32()
func pack(data []byte) []byte {
length := len(data)
packedData := make([]byte, 4+length)
copy(packedData[4:], data)
copy(packedData, []byte{byte(length >> 24), byte(length >> 16), byte(length >> 8), byte(length)})
return packedData
}
// binary.BigEndian.Uint32()
func unpack(packedData []byte) ([]byte, error) {
packedDataLen := len(packedData)
if packedDataLen < 4 {
return nil, fmt.Errorf("not enough bytes to unpack")
}
length := int(packedData[0])<<24 | int(packedData[1])<<16 | int(packedData[2])<<8 | int(packedData[3])
if packedDataLen < 4+length {
return nil, fmt.Errorf("not enough bytes to unpack")
}
return packedData[4 : 4+length], nil
}