假设我在linux中有一个Tcp服务器,它会为新的连接创建一个新的goroutine。当我想将数据写入tcp连接时,我应该像这样做
conn.Write(data)
或者在goroutine中进行,尤其是写作,就像这样
func writeRoutine(sendChan chan []byte){
for {
select {
case msg := <- sendChan :
conn.Write(msg)
}
}
}
以防网络繁忙。
简而言之,在写入套接字时,我是否需要使用c / c ++中的写缓冲区?
PS也许我没有清楚地解决这个问题。1我谈到了服务器,这意味着在Linux中运行的tcp服务器。它将为新的连接创造一个新的goroutine。像这样
listener, err := net.ListenTCP("tcp", tcpAddr)
if err != nil {
log.Error(err.Error())
os.Exit(-1)
}
for {
conn, err := listener.AcceptTCP()
if err != nil {
continue
}
log.Debug("Accept a new connection ", conn.RemoteAddr())
go handleClient(conn)
}
2我认为我的问题并不太关心代码。我们知道,当我们使用size_t write(int fd, const void *buf, size_t count);
在c / c ++中编写套接字fd时,对于tcp服务器,我们需要为代码中的套接字写一个缓冲区,或者可能只有部分数据写成功。我的意思是,我必须这样做吗?
答案 0 :(得分:2)
你实际上在这里问了两个不同的问题:
1)您应该在我的TCP服务器中使用每个接受的客户端连接goroutine吗? 2)给定一个[]字节,我应该如何写入连接?
对于1),答案是肯定的。这是最适合的模式类型。如果您查看net/http的源代码,您会看到它为每个连接生成一个goroutine。
对于2),你应该做与在c / c ++服务器中做同样的事情:写,检查写了多少并继续写,直到你完成,总是检查错误。以下是有关如何执行此操作的代码段:
func writeConn(data []byte) error {
var start,c int
var err error
for {
if c, err = conn.Write(data[start:]); err != nil {
return err
}
start += c
if c == 0 || start == len(data) {
break
}
}
return nil
}
答案 1 :(得分:1)
服务器[...]为新连接创建一个新的goroutine
这是有道理的,因为处理程序goroutines可以在不延迟服务器接受循环的情况下阻塞。
如果您按顺序处理每个请求,那么任何阻塞系统调用都会为所有客户端锁定服务器。
goroutine特别是写作
这只适用于您正在编写大量数据或非常慢的连接的用例,例如,您需要处理程序继续解除阻塞。
请注意,这不是通常被理解为&#34;写入缓冲区&#34;。