为了账号安全,请及时绑定邮箱和手机立即绑定

我需要一个用于套接字的写缓冲区吗?

我需要一个用于套接字的写缓冲区吗?

Go
qq_花开花谢_0 2021-09-13 14:24:46
假设我在 linux 中有一个 Tcp 服务器,它会为新的连接创建一个新的 goroutine。当我想向tcp连接写入数据时,我应该这样做吗conn.Write(data)或者在 goroutine 中做,特别是为了写作,像这样func writeRoutine(sendChan chan []byte){      for {       select {       case  msg := <- sendChan :          conn.Write(msg)       }      }}以防万一网络繁忙。简而言之,在写入套接字时,我是否需要像在 c/c++ 中一样在 go 中使用写缓冲区?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++写一个socket fd时,对于tcp server来说,你的代码中需要一个socket的写缓冲区,或者可能只有部分数据写入成功。我的意思是,我必须在 go 中这样做吗?
查看完整描述

2 回答

?
萧十郎

TA贡献1815条经验 获得超13个赞

您实际上在这里问了两个不同的问题:


1) 你应该在我的 TCP 服务器中为每个接受的客户端连接使用 goroutine 吗?2)给定一个[]字节,我应该如何写入连接?


对于 1),答案是肯定的。这是 go 最适合的模式类型。如果您查看net/http的源代码,您会看到它为每个连接生成一个 goroutine。


至于 2),你应该像在 ac/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

}


查看完整回答
反对 回复 2021-09-13
?
MMTTMM

TA贡献1869条经验 获得超4个赞

server [...] 为新的连接创建一个新的 goroutine

这是有道理的,因为处理程序 goroutine 可以在不延迟服务器接受循环的情况下阻塞。

如果您按顺序处理每个请求,则任何阻塞的系统调用实际上都会为所有客户端锁定服务器。

goroutine 特别适合写作

例如,这仅在您写入非常大的数据块或非常慢的连接并且您需要处理程序继续畅通无阻的用例中才有意义。

请注意,这不是通常理解的“写缓冲区”。


查看完整回答
反对 回复 2021-09-13
  • 2 回答
  • 0 关注
  • 158 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信