How to write a TCP chat server in 55 lines of Golang

The go net package lets you write a TCP server. Here’s a chat server, where every byte sent by a client is copied to every other client (including the sender).

package main
import "net"
func main() {
  newConns := make(chan net.Conn, 128)
  deadConns := make(chan net.Conn, 128)
  publishes := make(chan []byte, 128)
  conns := make(map[net.Conn]bool)
	listener, err := net.Listen("tcp", ":8080")
	if err != nil { panic(err) }
	go func() {
		for {
			conn, err := listener.Accept()
			if err != nil { panic(err) }
			newConns <- conn
		}
	}()
	for {
		select {
		case conn := <-newConns:
			conns[conn] = true
			go func() {
				buf := make([]byte, 1024)
				for {
					nbyte, err := conn.Read(buf)
					if err != nil {
						deadConns <- conn
						break
					} else {
						fragment := make([]byte, nbyte)
						copy(fragment, buf[:nbyte])
						publishes <- fragment
					}
				}
			}()
		case deadConn := <-deadConns:
			_ = deadConn.Close()
			delete(conns, deadConn)
		case publish := <-publishes:
			for conn, _ := range conns {
				go func(conn net.Conn) {
					totalWritten := 0
					for totalWritten < len(publish) {
						writtenThisCall, err := conn.Write(publish[totalWritten:])
						if err != nil {
							deadConns <- conn
							break
						}
						totalWritten += writtenThisCall
					}
				}(conn)
			}
		}
	}
	listener.Close()
}

Compare this to C:

Discussion on Hacker News.
Tagged .

Similar posts

More by Jim

Want to build a fantastic product using LLMs? I work at Granola where we're building the future IDE for knowledge work. Come and work with us! Read more or get in touch!

This page copyright James Fisher 2017. Content is not associated with my employer. Found an error? Edit this page.