go - 如何分别从服务器上运行的两个并发进程接收数据?

标签 go networking tcp concurrency server

我正在尝试构建一个基本的客户端/服务器架构,其中两者之间有一些数据交换,并且双方都有一些处理。所以我的服务器有两个线程正在向客户端发送一些数据。我想知道如何将这些数据分别接收到两个不同的变量中。

我了解到,尽管我仍然不确定,这与竞争条件、互斥锁等概念有关。我对它们有一个基本的了解,但从未实际使用过它们。我想知道关于这个问题是否有一些预先设计的解决方案。

服务器端:

func handleConn(conn net.Conn) {
    go func() {
        io.WriteString(conn, "Text 1")
    }()
    go func() {
        io.WriteString(conn, "Text 2")
    }()
}

客户端:

func SocketClient(ip string, port string) {
    addr := strings.Join([]string{ip, port}, ":")
    conn, err := net.Dial("tcp", addr)

    defer conn.Close()

    if err != nil {
        log.Fatalln(err)
    }

    buff := make([]byte, 1024)
    n, _ := conn.Read(buff)
    log.Printf("Received: %s", buff[:n])
}

“文本 1”和“文本 2”都由变量 buff 读取。我想让它看起来像有两个单独的变量 buff1 和 buff2 来分别保存两个文本。

最佳答案

您只读取一次连接,您应该期望在一次调用中接收到全部数据。 您可以使用换行符等分隔符分隔消息,并在循环中通过该分隔符读取数据。这样就好像您收到了两条不同的消息。我制作了一个 sample 供您查看。

package main

import (
    "bufio"
    "io"
    "log"
    "net"
    "sync"
)

func handleConn(conn net.Conn) {
    go func() {
        io.WriteString(conn, "Text 1\n")
    }()
    go func() {
        io.WriteString(conn, "Text 2\n")
    }()
}

func SocketClient() {
    conn, err := net.Dial("tcp", ":3000")
    if err != nil {
        log.Fatal(err)
    }
    defer conn.Close()
    if err != nil {
        log.Fatalln(err)
    }
    reader := bufio.NewReader(conn)
    for {
        buff, err := reader.ReadString('\n')
        if err != nil {
            log.Fatalln(err)
        }
        log.Printf("Received: %s", buff)
    }
}

func main() {
    wg := &sync.WaitGroup{}
    wg.Add(1)
    go func() {
        a, _ := net.Listen("tcp", ":3000")
        wg.Done()
        for {
            conn, err := a.Accept()
            if err != nil {
                log.Fatalln(err)
            }
            handleConn(conn)
        }
    }()
    wg.Wait()
    SocketClient()
}

输出:

Received: Text 1
Received: Text 2

关于go - 如何分别从服务器上运行的两个并发进程接收数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55520334/

相关文章:

c++ - 使用服务器的实际 IP 和端口连接到多播服务器

sockets - 如何使用AT命令可靠地拆除和重新连接TCP/IP套接字

ios - NSStream 委托(delegate)未触发错误

json - GoLang - 编码/json.Marshal 或 fmt.sprintf?

go - 如何在golang中捕获堆栈溢出错误

go - 如何正确导入 protobuf 的文件?

http - 关于http劫持和保活

http - 如何试用HTTP、FTP、SMTP等应用协议(protocol)

tcp - MQTT 如何在防火墙后工作?

java - 通过套接字读取 TCP 目标