douti0467 2018-05-25 08:55
浏览 21
已采纳

不正确的数据重传

I need my program to be in the middle of the connection and transfer data correctly in both directions. I wrote this code, but it does not work properly

package main

    import (
        "fmt"
        "net"
)

func main() {
    listener, err := net.Listen("tcp", ":8120")

    if err != nil {
        fmt.Println(err)
        return
    }
    defer listener.Close()
    fmt.Println("Server is listening...")
    for {
        var conn1, conn2 net.Conn
        var err error
        conn1, err = listener.Accept()
        if err != nil {
            fmt.Println(err)
            conn1.Close()
            continue
        }
        conn2, err = net.Dial("tcp", "185.151.245.51:80")
        if err != nil {
            fmt.Println(err)
            conn2.Close()
            continue
        }
        go handleConnection(conn1, conn2)
        go handleConnection(conn2, conn1)
    }
}

func handleConnection(conn1, conn2 net.Conn) {
    defer conn1.Close()
    for {
        input := make([]byte, 1024)
        n, err := conn1.Read(input)
        if n == 0 || err != nil {
            break
        }
        conn2.Write([]byte(input))
    }
}

The problem is that the data is corrupted, for example. enter image description here Left one is original, right one is what i got. End of the final gotten file is unreadable. enter image description here But at the beginnig everything is ok. I tried to change input slice size. If size > 0 and < 8, everything is fine, but slow. If i set input size very large, corruption of data become more awful. What I'm doing wrong?

  • 写回答

1条回答 默认 最新

  • dt250827 2018-05-25 09:24
    关注

    In handleConnection, you always write 1024 bytes, no matter what conn1.Read returns.

    You want to write the data like this:

    conn2.Write(input[:n])
    

    You should also check your top-level for loop. Are you sure you're not accepting multiple connections and smushing them all together? I'd sprinkle in some log statements so you can see when connections are made and closed.

    Another (probably inconsequential) mistake, is that you treat n==0 as a termination condition. In the documentation of io.Reader it's recommended that you ignore n==0, err==nil. Without checking the code I can't be sure, but I expect that conn.Read never returns n==0, err==nil, so it's unlikely that this is causing you trouble.

    Although it doesn't affect correctness, you could also lift the definition of input out of the loop so that it's reused on each iteration; it's likely to reduce the amount of work the garbage collector has to do.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥15 c++头文件不能识别CDialog
  • ¥15 Excel发现不可读取的内容
  • ¥15 关于#stm32#的问题:CANOpen的PDO同步传输问题