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 R语言Rstudio突然无法启动
  • ¥15 关于#matlab#的问题:提取2个图像的变量作为另外一个图像像元的移动量,计算新的位置创建新的图像并提取第二个图像的变量到新的图像
  • ¥15 改算法,照着压缩包里边,参考其他代码封装的格式 写到main函数里
  • ¥15 用windows做服务的同志有吗
  • ¥60 求一个简单的网页(标签-安全|关键词-上传)
  • ¥35 lstm时间序列共享单车预测,loss值优化,参数优化算法
  • ¥15 Python中的request,如何使用ssr节点,通过代理requests网页。本人在泰国,需要用大陆ip才能玩网页游戏,合法合规。
  • ¥100 为什么这个恒流源电路不能恒流?
  • ¥15 有偿求跨组件数据流路径图
  • ¥15 写一个方法checkPerson,入参实体类Person,出参布尔值