io.Copy between connection and file not working, while io.copy between the same connection and tcp is fine

Hi all,
I have a weird error: io.copy works fine in piping into a tcp connection, but it cannot send to a file the same bytes.
This is the relevant code:

connection, requests, err := newChannel.Accept()
if err != nil {
   log.Printf("Could not accept channel (%s)", err)
   return
}

remoteconnection, e := net.Dial("tcp", "127.0.0.1:7777")
if e != nil {
    log.Fatal("dialing: ", e.Error())
}

log.Printf("Connection: %#v", connection)

flowlog, err := os.Create("flowlog")
if err != nil {
    log.Fatal("error: ", e.Error())
}

//pipe session to bash and visa-versa
var once sync.Once
// Prepare teardown function
close := func() {
  log.Printf("closing connection..")
  remoteconnection.Close()
  flowlog.Close()
}
go func() {
   inl,err := io.Copy(connection,flowlog)
   if err != nil {
     log.Fatal("error: ", err.Error())
  }
  log.Printf("bytes written to log: %d", inl)
  in,_ := io.Copy(connection, remoteconnection)
  log.Printf("bytes in written: %d", in)
  io.Copy(connection,os.Stdout)
  flowlog.Sync()
 once.Do(close)
 }()

This is the output during my tests:

2017/10/04 17:14:07 bytes written to log: 0
2017/10/04 17:14:18 bytes in written: 12

I suspect the error is related to different type of destination…but I don’t how to solve it…

Please help me to understand and fix it.

Thanks in advance.

io.Copy takes destination, source.

func Copy(dst Writer, src Reader) (written int64, err error)

You’re copying flowlog (the file you just created, which is empty) to connection. (This mistake is possible because both flowlog and connection are both readers and writers…)

(You also seem to be wanting to copy the same bytes from the same connection twice. That’s not going to work, but you can use an io.MultiWriter to do what I think you want to do.)

Thanks, I need to copy the data I’m forwarding, I’ll have a look at MultiWriter now :wink:

I changed my program in

go func() {
  datadup := io.MultiWriter(remoteconnection,flowlog)
  n, err := datadup.Write(connection)
  if err != nil {
      log.Fatal("error: ", err.Error())
  } else {
      fmt.Printf("Multi write %d bytes to two files simultaneously.\n", n)
  }
  once.Do(close)

}()

but the type is not right for the Write method

 cannot use connection (type ssh.Channel) as type []byte in argument to datadup.Write

How can it be chaged to make it work?
Thanks

I solved my issue!
I used io.TeeReader, it works like a charm!