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. Left one is original, right one is what i got. End of the final gotten file is unreadable.
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?
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.