package main import ( "fmt" "net" "os" "syscall" ) const ( EPOLLET = 1 << 31 MaxEpollEvents = 32 ) func echo(fd int) { defer syscall.Close(fd) var buf [32 * 1024]byte for { nbytes, e := syscall.Read(fd, buf[:]) if nbytes > 0 { fmt.Printf(">>> %s", buf) syscall.Write(fd, buf[:nbytes]) fmt.Printf("<<< %s", buf) } if e != nil { break } } } func main() { var event syscall.EpollEvent var events [MaxEpollEvents]syscall.EpollEvent fd, err := syscall.Socket(syscall.AF_INET, syscall.O_NONBLOCK|syscall.SOCK_STREAM, 0) if err != nil { fmt.Println(err) os.Exit(1) } defer syscall.Close(fd) if err = syscall.SetNonblock(fd, true); err != nil { fmt.Println("setnonblock1: ", err) os.Exit(1) } addr := syscall.SockaddrInet4{Port: 2000} copy(addr.Addr[:], net.ParseIP("0.0.0.0").To4()) syscall.Bind(fd, &addr) syscall.Listen(fd, 10) epfd, e := syscall.EpollCreate1(0) if e != nil { fmt.Println("epoll_create1: ", e) os.Exit(1) } defer syscall.Close(epfd) event.Events = syscall.EPOLLIN event.Fd = int32(fd) if e = syscall.EpollCtl(epfd, syscall.EPOLL_CTL_ADD, fd, &event); e != nil { fmt.Println("epoll_ctl: ", e) os.Exit(1) } for { nevents, e := syscall.EpollWait(epfd, events[:], -1) if e != nil { fmt.Println("epoll_wait: ", e) break } for ev := 0; ev < nevents; ev++ { if int(events[ev].Fd) == fd { connFd, _, err := syscall.Accept(fd) if err != nil { fmt.Println("accept: ", err) continue } syscall.SetNonblock(fd, true) event.Events = syscall.EPOLLIN | EPOLLET event.Fd = int32(connFd) if err := syscall.EpollCtl(epfd, syscall.EPOLL_CTL_ADD, connFd, &event); err != nil { fmt.Print("epoll_ctl: ", connFd, err) os.Exit(1) } } else { go echo(int(events[ev].Fd)) } } } }