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

假设我在 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 中这样做吗?


qq_花开花谢_0
浏览 159回答 2
2回答

萧十郎

您实际上在这里问了两个不同的问题:1) 你应该在我的 TCP 服务器中为每个接受的客户端连接使用 goroutine 吗?2)给定一个[]字节,我应该如何写入连接?对于 1),答案是肯定的。这是 go 最适合的模式类型。如果您查看net/http的源代码,您会看到它为每个连接生成一个 goroutine。至于 2),你应该像在 ac/c++ 服务器中做的一样:写,检查写了多少,继续写直到你完成,总是检查错误。这是有关如何执行此操作的代码片段:func writeConn(data []byte) error {&nbsp; &nbsp; var start,c int&nbsp; &nbsp; var err error&nbsp; &nbsp; for {&nbsp; &nbsp; &nbsp; if c, err = conn.Write(data[start:]); err != nil {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return err&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; start += c&nbsp; &nbsp; &nbsp; if c == 0 || start == len(data) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; return nil}

MMTTMM

server [...] 为新的连接创建一个新的 goroutine这是有道理的,因为处理程序 goroutine 可以在不延迟服务器接受循环的情况下阻塞。如果您按顺序处理每个请求,则任何阻塞的系统调用实际上都会为所有客户端锁定服务器。goroutine 特别适合写作例如,这仅在您写入非常大的数据块或非常慢的连接并且您需要处理程序继续畅通无阻的用例中才有意义。请注意,这不是通常理解的“写缓冲区”。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go