I am trying to use a buffer to receive data from conn. I have a for loop around reader.Read and will break the loop when the reader comes back with an err stating EOF. However, it seems everything outside of the loop is no longer defined.
The second issue I am running into is I cannot append two slices. I try and use
dataFile = append(dataFile, buff)
but it says that I cannot use []byte. To my understanding you are able to append two slices like that. Where am I going wrong?
Here is the code:
import (
"fmt"
"net"
"log"
"bufio"
"os"
"io"
)
func readData(conn net.Conn){
fmt.Println("Reading data...\n")
// Create a new reader from conn
reader := bufio.NewReader(conn)
// Make a slice to hold all data being transmitted
var dataFile []byte
// Create a buffer to store information as it comes across conn
buff := make([]byte, 4096)
for {
bytesReturned, err := reader.Read(buff)
dataFile = append(dataFile, buff)
if err != nil {
if err != io.EOF{
log.Fatalln(err)
}
break //Break the loop when err returns EOF
}
}
err = os.WriteFile("data.txt", dataFile, 0666)
if err != nil {
log.Fatal(err)
}
fmt.Println("Read", bytesReturned,"bytes.")
}
// Start of main --------------------------------
func main(){
//Listen on local port 80
listener, err := net.Listen("tcp", ":5555")
if err != nil {
log.Fatalln("Unable to bind port")
}
fmt.Println("Port 5555 binded...\n")
//handle multiple connections
for {
conn, err := listener.Accept()
if err != nil {
log.Fatalln("Unable to accept connection...")
}
go readData(conn)
}
}
Here is a picture of the errors being received https://i.stack.imgur.com/7gJP9.png
CodePudding user response:
This line redefines bytesReturned
, shadowing the definition in the outer scope:
bytesReturned, err := reader.Read(buff)
Use:
var err error
bytesReturned, err = reader.Read(buff)
instead.
For appending, use append(dataFile, buff...)
Finally, err
is not defined, because the only err
used is in the for-loop, and since it is a different block, that err
is not recognized outside. Use:
err := os.WriteFile("data.txt", dataFile, 0666)
Instead.
Most of the program can be replaced with a call to io.Copy
.
CodePudding user response:
Append the bytes read, not the buffer itself.
bytesReturned, err := reader.Read(buff)
dataFile = append(dataFile, buff[:bytesReturned]...)
Note the use of the slice expression to get a slice of the bytes read and the ...
to specify the contents of the slice as the arguments to append
.
Use a short variable declaration to declare err
and assign the result of os.WriteFile to err
.
err := os.WriteFile("data.txt", dataFile, 0666)
if err != nil {
log.Fatal(err)
}
Use the length of the buffer to report the number of bytes read:
fmt.Println("Read", len(datafile),"bytes.")
Simplify the code by using io.ReadAll:
func readData(conn net.Conn) {
fmt.Println("Reading data...\n")
dataFile, err := io.ReadAll(conn)
if err != io.EOF {
log.Fatalln(err)
}
err = os.WriteFile("data.txt", dataFile, 0666)
if err != nil {
log.Fatal(err)
}
fmt.Println("Read", len(dataFile), "bytes.")
}