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()
}
server
复制代码

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()
}
client
复制代码

解决粘包的问题

复制代码
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
}
粘包
复制代码

 

posted @   扛把子修BUG  阅读(23)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
点击右上角即可分享
微信分享提示