title: TCP client / server file transfer in Go
body: <p>I'm new to Go and I'm having troubles debugging this client / server file transfer code. When I request a 719kb png file from the server, I get the 719kb.. but not perfectly, the png when I open it isn't completely displayed (some is cut off. Where am I going wrong here?</p>
  
  <pre><code>// CLIENT ///
      package main
  
  import (
      "bufio"
      "bytes"
      "fmt"
      "io"
      "log"
      "net"
      "os"
      "strings"
  )
  
  const BUFFER_SIZE = 1024
  
  func main() {
  
      //get port and ip address to dial
  
      if len(os.Args) != 3 {
          fmt.Println("useage example: tcpClient 127.0.0.1 7005")
          return
      }
  
      var ip string = os.Args[1]
      var port string = os.Args[2]
  
      connection, err := net.Dial("tcp", ip+":"+port)
      if err != nil {
          fmt.Println("There was an error making a connection")
      }
  
      //read from
      reader := bufio.NewReader(os.Stdin)
      fmt.Print("Please enter 'get &lt;filename&gt;' or 'send &lt;filename&gt;' to transfer files to the server\n\n")
      inputFromUser, _ := reader.ReadString('\n')
      arrayOfCommands := strings.Split(inputFromUser, " ")
  
      if arrayOfCommands[0] == "get" {
          getFileFromServer(arrayOfCommands[1], connection)
  
      } else if arrayOfCommands[0] == "send" {
          sendFileToServer(arrayOfCommands[1], connection)
      } else {
          fmt.Println("Bad Command")
      }
  
  }
  
  func sendFileToServer(fileName string, connection net.Conn) {
  
      var currentByte int64 = 0
      fmt.Println("send to client")
      fileBuffer := make([]byte, BUFFER_SIZE)
  
      var err error
  
      //file to read
      file, err := os.Open(strings.TrimSpace(fileName)) // For read access.
      if err != nil {
          connection.Write([]byte("-1"))
          log.Fatal(err)
      }
      connection.Write([]byte("send " + fileName))
      //read file until there is an error
      for err == nil || err != io.EOF {
  
          _, err = file.ReadAt(fileBuffer, currentByte)
          currentByte += BUFFER_SIZE
          fmt.Println(fileBuffer)
          connection.Write(fileBuffer)
      }
  
      file.Close()
      connection.Close()
  
  }
  
  func getFileFromServer(fileName string, connection net.Conn) {
  
      var currentByte int64 = 0
  
      fileBuffer := make([]byte, BUFFER_SIZE)
  
      var err error
      file, err := os.Create(strings.TrimSpace(fileName))
      if err != nil {
          log.Fatal(err)
      }
      connection.Write([]byte("get " + fileName))
      for {
  
          connection.Read(fileBuffer)
          cleanedFileBuffer := bytes.Trim(fileBuffer, "\x00")
  
          _, err = file.WriteAt(cleanedFileBuffer, currentByte)
  
          currentByte += BUFFER_SIZE
  
          if err == io.EOF {
              break
          }
  
      }
  
      file.Close()
      return
  
  }
  
  // END CLIENT //
  // SERVER //
      package main
  
  import (
      "bytes"
      "fmt"
      "io"
      "log"
      "net"
      "os"
      "strings"
  )
  
  const BUFFER_SIZE = 1024
  const PORT = "7005"
  
  func main() {
  
      fmt.Println("start listening")
  
      server, error := net.Listen("tcp", "localhost:"+PORT)
      if error != nil {
          fmt.Println("There was an error starting the server" + error.Error())
          return
      }
  
      //infinate loop
      for {
  
          connection, error := server.Accept()
          if error != nil {
              fmt.Println("There was am error with the connection" + error.Error())
              return
          }
          fmt.Println("connected")
          //handle the connection, on it's own thread, per connection
          go connectionHandler(connection)
      }
  }
  
  func connectionHandler(connection net.Conn) {
      buffer := make([]byte, BUFFER_SIZE)
  
      _, error := connection.Read(buffer)
      if error != nil {
          fmt.Println("There is an error reading from connection", error.Error())
          return
      }
      fmt.Println("command recieved: " + string(buffer))
  
      //loop until disconntect
  
      cleanedBuffer := bytes.Trim(buffer, "\x00")
      cleanedInputCommandString := strings.TrimSpace(string(cleanedBuffer))
      arrayOfCommands := strings.Split(cleanedInputCommandString, " ")
  
      fmt.Println(arrayOfCommands[0])
      if arrayOfCommands[0] == "get" {
          sendFileToClient(arrayOfCommands[1], connection)
      } else if arrayOfCommands[0] == "send" {
          fmt.Println("getting a file")
  
          getFileFromClient(arrayOfCommands[1], connection)
  
      } else {
          _, error = connection.Write([]byte("bad command"))
      }
  
  }
  
  func sendFileToClient(fileName string, connection net.Conn) {
      var currentByte int64 = 0
      fmt.Println("send to client")
      fileBuffer := make([]byte, BUFFER_SIZE)
  
      //file to read
      file, err := os.Open(strings.TrimSpace(fileName)) // For read access.
      if err != nil {
  
          log.Fatal(err)
      }
      var err2 error
  
      //read file until there is an error
      for {
  
          _, err2 = file.ReadAt(fileBuffer, currentByte)
          currentByte += BUFFER_SIZE
          fmt.Println(fileBuffer)
          connection.Write(fileBuffer)
  
          if err2 == io.EOF {
              break
          }
      }
  
      file.Close()
      return
  
  }
  
  func getFileFromClient(fileName string, connection net.Conn) {
  
      var currentByte int64 = 0
  
      fileBuffer := make([]byte, BUFFER_SIZE)
  
      var err error
      file, err := os.Create(strings.TrimSpace(fileName))
      if err != nil {
          log.Fatal(err)
      }
      connection.Write([]byte("get " + fileName))
      for err == nil || err != io.EOF {
  
          connection.Read(fileBuffer)
  
          cleanedFileBuffer := bytes.Trim(fileBuffer, "\x00")
  
          _, err = file.WriteAt(cleanedFileBuffer, currentByte)
          if len(string(fileBuffer)) != len(string(cleanedFileBuffer)) {
              break
          }
          currentByte += BUFFER_SIZE
  
      }
  
      connection.Close()
      file.Close()
      return
  
  }
  
  // END SERVER //
  </code></pre>