在TCP连接上多次写入数据

huangapple go评论92阅读模式
英文:

Write multiple time on TCP conn

问题

我有一个TCP服务器:
l, err := net.Listen("tcp", "localhost:"+strconv.Itoa(tcpPort))

服务器监听传入的客户端请求,如下所示:

for {
    c, err := l.Accept()
    if err != nil {
        log.Fatal(err)
    }
    b := make([]byte, 1024)
    c.Read(b)
    fmt.Println(string(b)) // "Hello"
}

我有一个客户端:
conn, err := net.Dial("tcp", address)

现在,我使用conn.Write([]byte("Hello"))写入一次。

服务器接收到了"Hello"。但是如果我有以下代码:

_, err := conn.Write([]byte("Hello"))
if err != nil {
    log.Fatal(err)
}

_, err = conn.Write([]byte("World"))
if err != nil {
    log.Fatal(err)
}

那么我只会得到"Hello",而不是"World"。

我该如何在同一个连接上多次写入?

以下是完整的函数:

func main() {
    l, err := net.Listen("tcp", "localhost:1234")
    if err != nil {
        log.Fatal(err)
    }
    defer l.Close()

    go func() {
        for {
            c, err := l.Accept()
            if err != nil {
                log.Fatal(err)
            }
            b := make([]byte, 1024)
            c.Read(b)
            fmt.Println(string(b))
        }
    }()

    conn, err := net.Dial("tcp", "localhost:1234")
    if err != nil {
        log.Fatal(err)
    }
    _, err = conn.Write([]byte("hello"))
    if err != nil {
        log.Fatal(err)
    }
    _, err = conn.Write([]byte("world"))
    if err != nil {
        log.Fatal(err)
    }
}
英文:

I have a TCP server server :
l, err := net.Listen("tcp", "localhost:"+strconv.Itoa(tcpPort))

The server listens to incoming client requests as is :

	for {
		c, err := l.Accept()
		if err != nil {
			log.Fatal(err)
		}
		b := make([]byte, 1024)
		c.Read(b)
        fmt.Println(string(b)) // "Hello"
    }

I have a client :
conn, err := net.Dial("tcp", address)

Now I I write once with conn.Write([]byte("Hello"))

The server catches Hello. But if I have these :

_, err := conn.Write([]byte("Hello"))
if err != nil {
    log.Fatal(err)
}

_, err = conn.Write([]byte("World"))
if err != nil {
    log.Fatal(err)
}

Then I will get Hello, but not World.

How can I write multiple time on the same connection ?

Full function below

func main() {
	l, err := net.Listen("tcp", "localhost:1234")
	if err != nil {
		log.Fatal(err)
	}
	defer l.Close()

	go func() {
		for {
			c, err := l.Accept()
			if err != nil {
				log.Fatal(err)
			}
			b := make([]byte, 1024)
			c.Read(b)
			fmt.Println(string(b))
		}

	}()

	conn, err := net.Dial("tcp", "localhost:1234")
	if err != nil {
		log.Fatal(err)
	}
	_, err = conn.Write([]byte("hello"))
	if err != nil {
		log.Fatal(err)
	}
	_, err = conn.Write([]byte("world"))
	if err != nil {
		log.Fatal(err)
	}
}

答案1

得分: 2

你的问题出在服务器代码中,即接收数据的部分。它只从TCP流中读取一次。如果你想要读取"world",需要将单个的read操作替换为一个循环:

go func() {
    for {
        c, err := l.Accept()
        if err != nil {
            log.Fatal(err)
        }
        for {
            b := make([]byte, 1024)
            c.Read(b)
            fmt.Println(string(b))
        }
    }
}()
英文:

Your problem is in the server code, the one that receives data. It only reads once from the tcp stream. If you want it to read "world", replace the single read operation by a loop:

go func() {
    for {
        c, err := l.Accept()
        if err != nil {
            log.Fatal(err)
        }
        for {
            b := make([]byte, 1024)
            c.Read(b)
            fmt.Println(string(b))
      }
    }
}()

答案2

得分: 1

你的问题不在于conn.Write,而是在于从连接中读取数据。现在你只是从每个新打开的连接中读取一次,通过l.Accept()接受。解决方法是进行重复读取。

你的代码也只能处理一个连接。不要忘记检查c.Read(b)的错误,以便知道何时停止监听该连接。

go func() {
	for {
		c, err := l.Accept()
		if err != nil {
			log.Fatal(err)
		}
		go func(conn net.Conn) {
			for {
				b := make([]byte, 1024)
				_, err := conn.Read(b)
				if err != nil {
					if err != io.EOF {
						fmt.Println("读取错误:", err)
					}
					break
				}
				fmt.Println(string(b))
			}
			fmt.Println("停止处理连接")
		}(c)
	}
}()
英文:

Your problem is not with conn.Write but with reading from connection. Now you read just once from every new opened connection accepted by l.Accept(). Solution is to read repeatedly.

Your code is also limited to handle just one connection. And do not forget to check error from c.Read(b) to know when stop listen on this connection.

go func() {
	for {
		c, err := l.Accept()
		if err != nil {
			log.Fatal(err)
		}
		go func(conn net.Conn) {
			for {
				b := make([]byte, 1024)
				_, err := conn.Read(b)
				if err != nil {
					if err != io.EOF {
						fmt.Println("read error:", err)
					}
					break
				}
				fmt.Println(string(b))
			}
			fmt.Println("Stopping handle connection")
		}(c)
	}
}()

huangapple
  • 本文由 发表于 2021年10月28日 20:49:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/69754411.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定