我是否需要写缓冲区插入套接字?

Suppose I had a Tcp server in linux, it would create a new goroutine for a new connnection. When I want to write data to the tcp connection, should I do it just like this

conn.Write(data)

or do it in a goroutine especially for writing, like this

func writeRoutine(sendChan chan []byte){
      for {
       select {
       case  msg := <- sendChan :
          conn.Write(msg)
       }
      }
}

just in case that the network was busy.

In a short, Did I need a write buffer in go just like in c/c++ when writing to a socket?

PS maybe I didn't exclaim the problem clearly.

1 I talked of the server, meaning a tcp server runing in linux. It would create a new goroutine for a new connnection. like this

   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 I think my problem isn't much concerned with the code. As we know, when we use size_t write(int fd, const void *buf, size_t count); to write a socket fd in c/c++, for a tcp server, we need a write buffer for a socket in your code necessaryly, or maybe only some of the data is writen successfully. I mean, Do I have to do so in go ?

server [...] create a new goroutine for a new connnection

This makes sense because the handler goroutines can block without delaying the server's accept loop.

If you handled each request serially, any blocking syscall would essentially lock up the server for all clients.

goroutine especially for writing

This would only make sense in use cases where you're writing either a really big chunk of data or to a very slow connection and you need your handler to continue unblocked, for instance.

Note that this is not what is commonly understood as a "write buffer".

You are actually asking two different questions here:

1) Should you use a goroutine per accepted client connection in my TCP server? 2) Given a []byte, how should I write to the connection?

For 1), the answer is yes. This is the type of pattern that go is most suited for. If you take a look at the source code for the net/http, you will see that it spawns a goroutine for each connection.

As for 2), you should do the same that you would do in a c/c++ server: write, check how much was written and keep on writing until your done, always checking for errors. Here is a code snippet on how to do it:

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
}