bugfix> go > 投稿

プログラムを接続の途中に置き、両方向にデータを正しく転送する必要があります。このコードを書きましたが、正しく動作しません

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))
    }
}

問題は、データが破損していることです。 例えば。左はオリジナル、右は私が手に入れたものです。 最終的に取得したファイルの終わりは判読できません。しかし、最初はすべて大丈夫です。 入力スライスサイズを変更しようとしました。サイズ> 0および<8、すべて問題ありませんが、遅いです。入力サイズを非常に大きく設定すると、データの破損がさらにひどくなります。 私が間違っているのは何ですか?

回答 1 件
  • handleConnection 、どんな conn1.Read でも、常に1024バイトを書き込む  戻り値。

    次のようにデータを書き込みます。

    conn2.Write(input[:n])
    
    

    また、トップレベルの for も確認する必要があります  ループ。複数の接続を受け入れて、それらをすべてまとめて押し込んでいないのですか?接続が行われ、閉じられたときに確認できるように、いくつかのログステートメントを振りかけます。

    別の(おそらく取るに足らない)間違いは、 n==0 を扱うことです。  終了条件として。 io.Reader のドキュメント内   n==0, err==nil を無視することをお勧めします 。コードをチェックせずに私は確信できませんが、私はその conn.Read を期待しています   n==0, err==nil を返さない 、したがって、これが問題を引き起こす可能性は低いです。

    正確性には影響しませんが、 input の定義を解除することもできます  ループから出て、各反復で再利用されるようにします。ガベージコレクターがしなければならない作業量を減らす可能性があります。

あなたの答え