func serve() { ep, err := netpoll.EpollCreate(epollConfig()) if err != nil { log.Fatal(err) } // Create listener on port 4444. ln, err := listen(4444) if err != nil { log.Fatal(err) } defer unix.Close(ln) done := make(chan struct{}) var received bytes.Buffer // Add listener fd to epoll instance to know when there are new incoming // connections. ep.Add(ln, netpoll.EPOLLIN, func(evt netpoll.EpollEvent) { if evt&_EPOLLCLOSED != 0 { return } // Accept new incoming connection. nfd, _, err := unix.Accept(ln) if err != nil { log.Fatalf("could not accept: %s", err) } // Socket must not block read() from it. unix.SetNonblock(nfd, true) // Add connection fd to epoll instance to get notifications about // available data. ep.Add( nfd, netpoll.EPOLLIN|netpoll.EPOLLET|netpoll.EPOLLHUP|netpoll.EPOLLRDHUP, func(evt netpoll.EpollEvent, ) { // If EPOLLRDHUP is supported, it will be triggered after conn // close() or shutdown(). In older versions EPOLLHUP is triggered. if evt&_EPOLLCLOSED != 0 { return } var buf [128]byte for { n, err := unix.Read(nfd, buf[:]) if err != nil { break } if n <= 0 { break } received.Write(buf[:n]) } bIo := bufio.NewReader(bytes.NewReader(received.Bytes())) req, err := http.ReadRequest(bIo) fmt.Println(req, err, "!!!!!!!!!") received.Reset() }) }) <- done if err = ep.Close(); err != nil { log.Fatal(err) } } func listen(port int) (ln int, err error) { fmt.Println("start server") ln, err = unix.Socket(unix.AF_INET, unix.O_NONBLOCK|unix.SOCK_STREAM, 0) if err != nil { return } // Need for avoid receiving EADDRINUSE error. // Closed listener could be in TIME_WAIT state some time. unix.SetsockoptInt(ln, unix.SOL_SOCKET, unix.SO_REUSEADDR, 1) addr := &unix.SockaddrInet4{ Port: port, Addr: [4]byte{0x7f, 0, 0, 1}, // 127.0.0.1 } if err = unix.Bind(ln, addr); err != nil { return } err = unix.Listen(ln, 4) return } func epollConfig() *netpoll.EpollConfig { return &netpoll.EpollConfig{ OnWaitError: func(err error) { log.Fatal(err) }, } }