github.com/iceber/iouring-go@v0.0.0-20230403020409-002cfd2e2a90/examples/echo-with-callback/server.go (about) 1 package main 2 3 import ( 4 "fmt" 5 "net" 6 "os" 7 "syscall" 8 9 "github.com/iceber/iouring-go" 10 ) 11 12 const readSize = 1024 13 14 var ( 15 iour *iouring.IOURing 16 resulter chan iouring.Result 17 ) 18 19 func main() { 20 if len(os.Args) != 2 { 21 fmt.Printf("Usage: %s <host:port>\n", os.Args[0]) 22 return 23 } 24 25 var err error 26 iour, err = iouring.New(1024) 27 if err != nil { 28 panic(err) 29 } 30 defer iour.Close() 31 32 resulter = make(chan iouring.Result, 10) 33 34 fd := listenSocket(os.Args[1]) 35 prepAccept := iouring.Accept(fd).WithCallback(accept) 36 if _, err := iour.SubmitRequest(prepAccept, resulter); err != nil { 37 panicf("submit accept request error: %v", err) 38 } 39 40 fmt.Println("echo server running...") 41 for result := range resulter { 42 result.Callback() 43 } 44 } 45 46 func accept(result iouring.Result) error { 47 prepAccept := iouring.Accept(result.Fd()).WithCallback(accept) 48 if _, err := iour.SubmitRequest(prepAccept, resulter); err != nil { 49 panicf("submit accept request error: %v", err) 50 } 51 52 if err := result.Err(); err != nil { 53 panicf("accept error: %v", err) 54 } 55 56 connFd := result.ReturnValue0().(int) 57 sockaddr := result.ReturnValue1().(*syscall.SockaddrInet4) 58 59 clientAddr := fmt.Sprintf("%s:%d", net.IPv4(sockaddr.Addr[0], sockaddr.Addr[1], sockaddr.Addr[2], sockaddr.Addr[3]), sockaddr.Port) 60 fmt.Printf("Client Conn: %s\n", clientAddr) 61 62 buffer := make([]byte, readSize) 63 prep := iouring.Read(connFd, buffer).WithInfo(clientAddr).WithCallback(read) 64 if _, err := iour.SubmitRequest(prep, resulter); err != nil { 65 panicf("submit read request error: %v", err) 66 } 67 return nil 68 } 69 70 func read(result iouring.Result) error { 71 clientAddr := result.GetRequestInfo().(string) 72 if err := result.Err(); err != nil { 73 panicf("[%s] read error: %v", clientAddr, err) 74 } 75 76 num := result.ReturnValue0().(int) 77 buf, _ := result.GetRequestBuffer() 78 content := buf[:num] 79 80 connPrintf(clientAddr, "read byte: %v\ncontent: %s\n", num, content) 81 82 prep := iouring.Write(result.Fd(), content).WithInfo(clientAddr).WithCallback(write) 83 if _, err := iour.SubmitRequest(prep, resulter); err != nil { 84 panicf("[%s] submit write request error: %v", clientAddr, err) 85 } 86 return nil 87 } 88 89 func write(result iouring.Result) error { 90 clientAddr := result.GetRequestInfo().(string) 91 if err := result.Err(); err != nil { 92 panicf("[%s] write error: %v", clientAddr, err) 93 } 94 connPrintf(clientAddr, "write successful\n") 95 96 prep := iouring.Close(result.Fd()).WithInfo(clientAddr).WithCallback(close) 97 if _, err := iour.SubmitRequest(prep, resulter); err != nil { 98 panicf("[%s] submit write request error: %v", clientAddr, err) 99 } 100 return nil 101 } 102 103 func close(result iouring.Result) error { 104 clientAddr := result.GetRequestInfo().(string) 105 if err := result.Err(); err != nil { 106 panicf("[%s] close error: %v", clientAddr, err) 107 } 108 connPrintf(clientAddr, "close successful\n") 109 return nil 110 } 111 112 func listenSocket(addr string) int { 113 fd, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_STREAM, 0) 114 if err != nil { 115 panic(err) 116 } 117 118 tcpAddr, err := net.ResolveTCPAddr("tcp", addr) 119 if err != nil { 120 panic(err) 121 } 122 123 sockaddr := &syscall.SockaddrInet4{Port: tcpAddr.Port} 124 copy(sockaddr.Addr[:], tcpAddr.IP.To4()) 125 if err := syscall.Bind(fd, sockaddr); err != nil { 126 panic(err) 127 } 128 129 if err := syscall.Listen(fd, syscall.SOMAXCONN); err != nil { 130 panic(err) 131 } 132 return fd 133 } 134 135 func panicf(format string, a ...interface{}) { 136 panic(fmt.Sprintf(format, a...)) 137 } 138 139 func connPrintf(addr string, format string, a ...interface{}) { 140 prefix := fmt.Sprintf("[%s]", addr) 141 fmt.Printf(prefix+format, a...) 142 }