source: examples/io/simple/server.c@ 7215000

ADT arm-eh ast-experimental enum forall-pointer-decay jacob/cs343-translation new-ast new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since 7215000 was 63863f8, checked in by Thierry Delisle <tdelisle@…>, 5 years ago

Started some clean-up in examples/io

  • Property mode set to 100644
File size: 3.3 KB
Line 
1#include <assert.h>
2#include <stdio.h>
3#include <stdlib.h>
4#include <string.h>
5
6#include <unistd.h>
7
8#include <sys/types.h>
9#include <sys/socket.h>
10#include <netinet/in.h>
11
12#include <liburing.h>
13
14struct io_uring ring;
15
16char data[256];
17struct iovec iov = { data, 256 };
18struct msghdr msg = { "", 0, &iov, 1, NULL, 0, 0 };
19static void async_read(int sock) {
20 /* get an sqe and fill in a READ operation */
21 struct io_uring_sqe * sqe = io_uring_get_sqe(&ring);
22 io_uring_prep_recvmsg(sqe, sock, &msg, 0);
23 sqe->user_data = 0;
24
25 /* tell the kernel we have an sqe ready for consumption */
26 int ret = io_uring_submit(&ring);
27 assert(ret == 1);
28}
29
30int main(int argc, char *argv[]) {
31 if(argc != 2) {
32 printf("usage: %s portnumber\n", argv[0]);
33 exit( EXIT_FAILURE );
34 }
35 int port = atoi(argv[1]);
36 if(port < 1) {
37 printf("Invalid port : %d (from %s)\n", port, argv[1]);
38 exit( EXIT_FAILURE );
39 }
40
41 int sock = socket(AF_INET, SOCK_STREAM, 0);
42 if(sock < 0) {
43 perror( "socket" );
44 exit( EXIT_FAILURE );
45 }
46
47 struct sockaddr_in serv_addr;
48 memset(&serv_addr, 0, sizeof(serv_addr));
49 serv_addr.sin_family = AF_INET;
50 serv_addr.sin_addr.s_addr = INADDR_ANY;
51 serv_addr.sin_port = htons(port);
52
53 int ret = bind(sock, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
54 if(ret < 0) {
55 perror( "bind" );
56 exit( EXIT_FAILURE );
57 }
58
59
60 listen(sock,1);
61
62 struct sockaddr_in cli_addr;
63 __socklen_t clilen = sizeof(cli_addr);
64 int newsock = accept(sock, (struct sockaddr *) &cli_addr, &clilen);
65 if (newsock < 0) {
66 perror( "accept" );
67 exit( EXIT_FAILURE );
68 }
69
70 io_uring_queue_init( 16, &ring, 0 );
71
72 async_read( newsock );
73
74 while(1) {
75 struct io_uring_cqe * cqe;
76 struct __kernel_timespec ts = { 2, 0 };
77 // int ret = io_uring_wait_cqes( &ring, &cqe, 1, &ts, NULL); // Requires Linux 5.4
78 int ret = io_uring_wait_cqe( &ring, &cqe );
79
80 if( ret < 0 ) {
81 printf( "Main Loop Error : %s\n", strerror(-ret) );
82 close( sock );
83 exit( EXIT_FAILURE );
84 }
85
86 switch(cqe->user_data) {
87 // Read completed
88 case 0:
89 // If it is the end of file we are done
90 if( cqe->res == 0 ) {
91 goto END;
92 }
93
94 if( cqe->res < 0 ) {
95 perror( "Main Loop Error" );
96 close( sock );
97 exit( EXIT_FAILURE );
98 }
99
100 printf("'%.*s'\n", cqe->res, data);
101
102 async_read( newsock );
103
104 // otherwise prepare a new read
105 break;
106 // Wait timed out, time to print
107 // Requires Linux 5.4
108 case LIBURING_UDATA_TIMEOUT:
109 printf(".");
110 break;
111 // Problem
112 default:
113 printf("Unexpected user data : %llu", cqe->user_data);
114 exit( EXIT_FAILURE );
115 }
116
117 io_uring_cqe_seen( &ring, cqe );
118 }
119END:
120
121 io_uring_queue_exit( &ring );
122
123 ret = close(newsock);
124 if(ret < 0) {
125 perror( "close new" );
126 exit( EXIT_FAILURE );
127 }
128
129 ret = close(sock);
130 if(ret < 0) {
131 perror( "close old" );
132 exit( EXIT_FAILURE );
133 }
134
135 return 0;
136}
Note: See TracBrowser for help on using the repository browser.