dtcmadj31951 2018-09-17 13:12
浏览 27
已采纳

代理处理程序函数中[] byte的字符串表示形式

I am building a TCP proxy with go, but I am facing a small problem. Before actually handling the connection c1 and forwarding it to c2, I want to do some checks. To do this, I need the string representation of the byte slice from c1. Unfortunately, _, err := io.CopyBuffer(w, r, buf) is copying the []byte directly between the writer and reader, and if I do c1.Read() before the cp function, the []byte have already been read.

Here is the function containing the connection handling:

 func (p *proxy) handle(c1 net.Conn) {
        p.log.Printf("accepted %v", c1.RemoteAddr())
        defer p.log.Printf("disconnected %v", c1.RemoteAddr())
        defer c1.Close()
        c2, err := dialer.Dial("tcp", p.dial)
        log.Println("DIAL:", p.dial)
        if err != nil {
            p.log.Print("C2", err)
            return
        }
        defer c2.Close()

        errc := make(chan error, 2)
        cp := func(w io.Writer, r io.Reader) {
            buf := bufferPool.Get().([]byte)
            _, err := io.CopyBuffer(w, r, buf)
            errc <- err
            bufferPool.Put(buf)
        }
        go cp(struct{ io.Writer }{c1}, c2)
        go cp(c2, struct{ io.Reader }{c1})
        err = <-errc
        if err != nil {
            p.log.Print("F-ERROR ->", err)
        }
    }

Is there a way to "duplicate" the []byte so that I can use the duplicate to display as a string?

  • 写回答

1条回答 默认 最新

  • doumo3903 2018-09-17 13:39
    关注

    You can use io.MultiReader to concatenate two or more readers. So you can Read() from c1, and then use a MultiReader to "replay" the bytes you already read.

    package main
    
    import (
        "bytes"
        "io"
        "log"
        "net"
    )
    
    func main() {
        var c1, c2 net.Conn
    
        buf := make([]byte, 64)
        n, err := c1.Read(buf)
        buf = buf[:n]
        if err != nil {
            log.Fatal(err)
        }
    
        // TODO: deal with string(buf)
    
        errc := make(chan error, 2)
    
        go func() {
            // Replay contents of buf, then copy the unread part of c1.
            _, err := io.Copy(c2, io.MultiReader(bytes.NewReader(buf), c1))
            errc <- err
        }()
    
        go func() {
            _, err := io.Copy(c1, c2)
            errc <- err
        }()
    
        err = <-errc
        log.Println(err)
    }
    

    Alternatively, simply Write() the bytes before starting to copy:

        go func() {
            // Replay contents of buf
            _, err := c2.Write(buf)
            if err != nil {
                errc <- err
                return
            }
    
            _, err = io.Copy(c2, c1)
            errc <- err
        }()
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 求个正点原子stm32f407开发版的贪吃蛇游戏
  • ¥15 正弦信号发生器串并联电路电阻无法保持同步怎么办
  • ¥15 划分vlan后,链路不通了?
  • ¥20 求各位懂行的人,注册表能不能看到usb使用得具体信息,干了什么,传输了什么数据
  • ¥15 个人网站被恶意大量访问,怎么办
  • ¥15 Vue3 大型图片数据拖动排序
  • ¥15 Centos / PETGEM
  • ¥15 划分vlan后不通了
  • ¥20 用雷电模拟器安装百达屋apk一直闪退
  • ¥15 算能科技20240506咨询(拒绝大模型回答)