Created
October 24, 2018 21:09
-
-
Save filinvadim/cbdea1c46e6f30195a2cb03254b8c6ae to your computer and use it in GitHub Desktop.
Revisions
-
Vadim Filin created this gist
Oct 24, 2018 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,101 @@ 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) }, } }