3

I have this Go tcp socket

package main import ( "fmt" "io" "log" "net" "bytes" ) func main() { l, err := net.Listen("tcp", ":1200") if err != nil { log.Fatal(err) } defer l.Close() for { conn, err := l.Accept() if err != nil { log.Fatal(err) } go func(c net.Conn) { var buf bytes.Buffer io.Copy(&buf, c) fmt.Println("total size:", buf.Len()) s := buf.String() println(s) c.Close() }(conn) } } 

accept a message, transform it to string and display it, but if the connection is not closed by the client I am not able to see the message showed on the server as expected

How is possible to send multiple message from the client without the need to close the client connection (by the client) ?

Here the client in NodeJs

var net = require('net'); let packet = { Target: { Host: "", Port: "9000" }, Name: { Family: "Newmarch", Personal: "Jan" }, Email: [ { Kind: "home", Address: "[email protected]"}, { Kind: "work", Address: "[email protected]"} ] } var client = new net.Socket(); client.connect(1200, '0.0.0.0', function() { console.log('Connected'); client.write( (new Buffer(JSON.stringify(packet), 'UTF-8')) ); client.end(); //client.write('\n'); }); client.on('data', function(data) { console.log('Received: ' + data); client.destroy(); }); client.on('close', function() { console.log('Connection closed'); }); 

Thanks valeriano cossu

1
  • As the answers mentioned you have to break your messages somehow. TCP itself is a streaming protocol, not a packet based one. Commented Sep 8, 2016 at 7:58

2 Answers 2

4

Because you are getting a constant stream of data the server needs to know how to seperate messages. One way of doing that is using a new line character.

I have revised your code below.

Go server: package main

import ( "bufio" "log" "net" ) func main() { l, err := net.Listen("tcp", ":1200") if err != nil { log.Fatal(err) } defer l.Close() for { conn, err := l.Accept() if err != nil { log.Fatal(err) } go func(c net.Conn) { for { message, err := bufio.NewReader(conn).ReadString('\n') if err != nil { log.Printf("Error: %+v", err.Error()) return } log.Println("Message:", string(message)) } }(conn) } } 

Nodejs client:

var net = require('net'); let packet = { Target: { Host: "", Port: "9000" }, Name: { Family: "Newmarch", Personal: "Jan" }, Email: [ { Kind: "home", Address: "[email protected]"}, { Kind: "work", Address: "[email protected]"} ] } var client = new net.Socket(); client.connect(1200, '0.0.0.0', function() { console.log('Connected'); // Send 10 messages for(var i = 0; i < 10; i++) { client.write( (new Buffer(JSON.stringify(packet), 'UTF-8')) ); client.write('\n'); } client.end(); }); client.on('data', function(data) { console.log('Received: ' + data); client.destroy(); }); client.on('close', function() { console.log('Connection closed'); }); 
Sign up to request clarification or add additional context in comments.

Comments

1

From the io package documentation: https://golang.org/pkg/io/#Copy , the Copy function copies until it encounters EOF.

You don't send EOF manually but the client closing the connection does that, so the Copy function can finish the copying.

You can use bufio package to read strings with your delimiter:

line, err := bufio.NewReader(conn).ReadString('\n') 

In the above case, the delimiter is new line character. You can reuse the reader to repeatedly call ReadString on it to retrieve more messages.

2 Comments

Thanks Nebril, it's right, now work as explained by Tomaz too.
@internet3 great to know, feel free to accept either mine or Tomaz's answer (tick under answer score).

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.