golang 之socket-tcp
tcp-server

package main import ( "bufio" "fmt" "io" "net" "os" "strings" proto "github.com/guozh10/08day/04tcp_demo/protocol" ) // tcp server func processConn(conn net.Conn){ defer conn.Close() // 3. 与客户端通信 var tmp [1024]byte reader := bufio.NewReader(os.Stdin) for { n ,err :=conn.Read(tmp[:]) if err != nil{ fmt.Println("read from conn failed err",err) return } fmt.Println(string(tmp[:n])) msg ,_ := reader.ReadString('\n') msg = strings.TrimSpace(msg) conn.Write([]byte(msg)) } } func processConn1(conn net.Conn) { defer conn.Close() reader := bufio.NewReader(conn) for { recvStr , err := proto.Decode(reader) if err == io.EOF{ return } if err !=nil{ fmt.Println("decode failed err",err) return } fmt.Println("收到client 发来的数据",recvStr) } } func tcpserver(){ // 1. 本地启动服务 listener, err := net.Listen("tcp","127.0.0.1:30000") if err != nil{ fmt.Println("start tcp server on 127.0.0.1:30000 failed ,err",err) return } // 2. 等待别人跟我链接 for { conn, err :=listener.Accept() if err != nil{ fmt.Println("accept failed,err",err) return } // go processConn(conn) go processConn1(conn) } } func main(){ tcpserver() }
tcp client

package main import ( "bufio" "fmt" "net" "os" "strings" proto "github.com/guozh10/08day/04tcp_demo/protocol" ) //tcp client func sendData(conn net.Conn){ // 2. 发送数据 // var msg string // if len(os.Args) < 2 { // msg = "hello zhangsan" // }else{ // msg = os.Args[1] // } reader := bufio.NewReader(os.Stdin) for { fmt.Print("请输入:") msg , err := reader.ReadString('\n') if err != nil{ fmt.Println("readString tailed err",err) } msg = strings.TrimSpace(msg) if msg == "exit" { break } conn.Write([]byte(msg)) } } func sendData1(conn net.Conn){ defer conn.Close() reader := bufio.NewReader(os.Stdin) for { fmt.Print("请输入:") msg , err := reader.ReadString('\n') if err != nil{ fmt.Println("readString tailed err",err) } // 调用协议编码数据 b , err := proto.Encode(msg) if err !=nil{ fmt.Println("encode failed err",err) return } conn.Write(b) } } func tcpclient(){ // 1. 与serverd端建立连接 conn, err := net.Dial("tcp","127.0.0.1:30000") if err != nil{ fmt.Println("dial 127.0.0.1:30000 failed,err",err) return } // sendData(conn) sendData1(conn) } func main(){ tcpclient() }
解决粘包的问题

package proto import ( "bufio" "bytes" "encoding/binary" ) //将消息编码 func Encode(message string) ([]byte,error) { // 读取消息的长度,转换成int32 类型 var length = int32(len(message)) var pkg = new(bytes.Buffer) // 写入消息头 err := binary.Write(pkg,binary.LittleEndian,length) if err != nil{ return nil, err } // 写入消息实体 err = binary.Write(pkg,binary.LittleEndian,[]byte(message)) if err != nil { return nil , err } return pkg.Bytes(),nil } //将消息解码 func Decode(reder *bufio.Reader) (string ,error){ //读取消息的长度, // 读取前4个字节数据 lengthBtye, _ := reder.Peek(4) lengthBuff := bytes.NewBuffer(lengthBtye) var length int32 err := binary.Read(lengthBuff,binary.LittleEndian,&length) if err != nil{ return "",err } // Buffered 返回缓冲中现有的可读的字节数。 if int32(reder.Buffered()) < length+4{ return "",err } // 读取真正的消息数据 pack := make([]byte,int(4+length)) _,err = reder.Read(pack) if err != nil{ return "",err } return string(pack[4:]), nil }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南