I try to create TCP client to receive data from TCP server, but after server sending data only I receive data one even if server send many data, and I want to receive data forever, and I don't know what is my problem,and
Client:
func main() {
tcpAddr := "localhost:3333"
conn, err := net.DialTimeout("tcp", tcpAddr, time.Second*7)
if err != nil {
log.Println(err)
}
defer conn.Close()
// conn.Write([]byte("Hello World"))
connBuf := bufio.NewReader(conn)
for {
bytes, err := connBuf.ReadBytes('\n')
if err != nil {
log.Println("Rrecv Error:", err)
}
if len(bytes) > 0 {
fmt.Println(string(bytes))
}
time.Sleep(time.Second * 2)
}
}
I'm following this example to create TCP test server
Server:
// Handles incoming requests.
func handleRequest(conn net.Conn) {
// Make a buffer to hold incoming data.
buf := make([]byte, 1024)
// Read the incoming connection into the buffer.
_, err := conn.Read(buf)
if err != nil {
fmt.Println("Error reading:", err.Error())
}
fmt.Println(buf)
// Send a response back to person contacting us.
var msg string
fmt.Scanln(&msg)
conn.Write([]byte(msg))
// Close the connection when you're done with it.
conn.Close()
}
CodePudding user response:
Read requires a Write on the other side of the connection
want to receive data forever
Then you have to send data forever. There's a for
loop on the receiving end, but no looping on the sending end. The server writes its message once and closes the connection.
Server expects to get msg from client but client doesn't send it
// conn.Write([]byte("Hello World"))
That's supposed to provide the msg
value to the server
_, err := conn.Read(buf)
So those two lines don't match.
Client expects a newline but server isn't sending one
fmt.Scanln
expects to put each whitespace separated value into the corresponding argument. It does not capture the whitespace. So:
- Only up to the first whitespace of what you type into server's stdin will be stored in
msg
- Newline will not be stored in
msg
.
But your client is doing
bytes, err := connBuf.ReadBytes('\n')
The \n
never comes. The client never gets done reading that first msg
.
bufio.NewScanner
would be a better way to collect data from stdin, since you're likely to want to capture whitespace as well. Don't forget to append the newline to each line of text you send, because the client expects it!
Working code
I put these changes together into a working example on the playground. To get it working in that context, I had to make a few other changes too.
- Running server and client in the same process
- Hard coded 3 clients so the program ended in limited amount of time
- Hard coded 10 receives in the client so program can end
- Hard coded 3 server connections handled so program can end
- Removed
fmt.Scanln
and have server just return the original message sent (because playground provides no stdin mechanism)
Should be enough to get you started.