golang tcp socket - 处理多条消息

时间:2016-09-07 10:44:50

标签: node.js sockets go tcp

我有这个Go tcp套接字

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)
  }
}

接受消息,将其转换为字符串并显示它,但如果客户端没有关闭连接,我将无法按预期看到服务器上显示的消息

如何在不需要关闭客户端连接的情况下(客户端)从客户端发送多条消息?

这里是NodeJs中的客户端

var net = require('net');

let packet = {
              Target: { Host: "", Port: "9000" },
              Name: { Family: "Newmarch", Personal: "Jan" },
              Email: [
                      { Kind: "home", Address: "jan@newmarch.name"},
                      { Kind: "work", Address: "j.newmarch@boxhill.edu.au"}
                     ]
}


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');
});

感谢valeriano cossu

2 个答案:

答案 0 :(得分:3)

因为您正在获得恒定的数据流,所以服务器需要知道如何分离消息。一种方法是使用换行符。

我在下面修改了你的代码。

去服务器:     包主要

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客户端:

var net = require('net');

let packet = {
              Target: { Host: "", Port: "9000" },
              Name: { Family: "Newmarch", Personal: "Jan" },
              Email: [
                      { Kind: "home", Address: "jan@newmarch.name"},
                      { Kind: "work", Address: "j.newmarch@boxhill.edu.au"}
                     ]
}


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');
});

答案 1 :(得分:1)

io包文档:https://golang.org/pkg/io/#Copy,复制功能会复制,直到遇到EOF。

您不能手动发送EOF,但关闭连接的客户端会这样做,因此复制功能可以完成复制。

您可以使用bufio包来使用分隔符读取字符串:

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

在上面的例子中,分隔符是换行符。您可以重复使用阅读器在其上重复调用ReadString以检索更多消息。