xref: /f-stack/example/main_zc.c (revision 1f5a5310)
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <stdint.h>
4 #include <string.h>
5 #include <strings.h>
6 #include <sys/types.h>
7 #include <sys/socket.h>
8 #include <arpa/inet.h>
9 #include <errno.h>
10 #include <assert.h>
11 
12 #include "ff_config.h"
13 #include "ff_api.h"
14 
15 #define MAX_EVENTS 512
16 
17 /* kevent set */
18 struct kevent kevSet;
19 /* events */
20 struct kevent events[MAX_EVENTS];
21 /* kq */
22 int kq;
23 int sockfd;
24 #ifdef INET6
25 int sockfd6;
26 #endif
27 
28 char html[] =
29 "HTTP/1.1 200 OK\r\n"
30 "Server: F-Stack\r\n"
31 "Date: Sat, 25 Feb 2017 09:26:33 GMT\r\n"
32 "Content-Type: text/html\r\n"
33 "Content-Length: 438\r\n"
34 "Last-Modified: Tue, 21 Feb 2017 09:44:03 GMT\r\n"
35 "Connection: keep-alive\r\n"
36 "Accept-Ranges: bytes\r\n"
37 "\r\n"
38 "<!DOCTYPE html>\r\n"
39 "<html>\r\n"
40 "<head>\r\n"
41 "<title>Welcome to F-Stack!</title>\r\n"
42 "<style>\r\n"
43 "    body {  \r\n"
44 "        width: 35em;\r\n"
45 "        margin: 0 auto; \r\n"
46 "        font-family: Tahoma, Verdana, Arial, sans-serif;\r\n"
47 "    }\r\n"
48 "</style>\r\n"
49 "</head>\r\n"
50 "<body>\r\n"
51 "<h1>Welcome to F-Stack!</h1>\r\n"
52 "\r\n"
53 "<p>For online documentation and support please refer to\r\n"
54 "<a href=\"http://F-Stack.org/\">F-Stack.org</a>.<br/>\r\n"
55 "\r\n"
56 "<p><em>Thank you for using F-Stack.</em></p>\r\n"
57 "</body>\r\n"
58 "</html>";
59 
60 
61 char html1[] =
62 "HTTP/1.1 200 OK\r\n"
63 "Server: F-Stack\r\n"
64 "Date: Sat, 25 Feb 2017 09:26:33 GMT\r\n"
65 "Content-Type: text/html\r\n"
66 "Content-Length: 9438\r\n"
67 "Last-Modified: Tue, 21 Feb 2017 09:44:03 GMT\r\n"
68 "Connection: keep-alive\r\n"
69 "Accept-Ranges: bytes\r\n"
70 "\r\n"
71 "<!DOCTYPE html>\r\n"
72 "<html>\r\n"
73 "<head>\r\n"
74 "<title>Welcome to F-Stack!</title>\r\n"
75 "<style>\r\n"
76 "    body {  \r\n"
77 "        width: 35em;\r\n"
78 "        margin: 0 auto; \r\n"
79 "        font-family: Tahoma, Verdana, Arial, sans-serif;\r\n"
80 "    }\r\n"
81 "</style>\r\n"
82 "</head>\r\n"
83 "<body>\r\n"
84 "<h1>Welcome to F-Stack!</h1>\r\n"
85 "\r\n"
86 "<p>For online documentation and support please refer to012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234"
87 
88 "5678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234"
89 
90 "56789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\r\n"
91 "<a href=\"http://F-Stack.org/\">F-Stack.org</a>.<br/>\r\n"
92 "\r\n"
93 "<p><em>Thank you for using F-Stack.</em></p>\r\n"
94 "</body>\r\n"
95 "</html>";
96 
97 char html2[] =
98 "HTTP/1.1 200 OK\r\n"
99 "Server: F-Stack\r\n"
100 "Date: Sat, 25 Feb 2017 09:26:33 GMT\r\n"
101 "Content-Type: text/html\r\n"
102 "Content-Length: 1228\r\n"
103 "Last-Modified: Tue, 21 Feb 2017 09:44:03 GMT\r\n"
104 "Connection: keep-alive\r\n"
105 "Accept-Ranges: bytes\r\n"
106 "\r\n"
107 "<!DOCTYPE html>\r\n"
108 "<html>\r\n"
109 "<head>\r\n"
110 "<title>Welcome to F-Stack!</title>\r\n"
111 "<style>\r\n"
112 "    body {  \r\n"
113 "        width: 35em;\r\n"
114 "        margin: 0 auto; \r\n"
115 "        font-family: Tahoma, Verdana, Arial, sans-serif;\r\n"
116 "    }\r\n"
117 "</style>\r\n"
118 "</head>\r\n"
119 "<body>\r\n"
120 "<h1>Welcome to F-Stack!</h1>\r\n"
121 "\r\n"
122 "<p>For online documentation and support please refer to0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\r\n"
123 "<a href=\"http://F-Stack.org/\">F-Stack.org</a>.<br/>\r\n"
124 "\r\n"
125 "<p><em>Thank you for using F-Stack.</em></p>\r\n"
126 "</body>\r\n"
127 "</html>";
128 
129 extern int ff_zc_mbuf_get(struct ff_zc_mbuf *m, int len);
130 extern int ff_zc_mbuf_write(struct ff_zc_mbuf *m, const char *data, int len);
131 
132 char *buf_tmp;
133 char html_buf[10240];
134 size_t buf_len = 0;
135 struct ff_zc_mbuf zc_buf;
136 
loop(void * arg)137 int loop(void *arg)
138 {
139     /* Wait for events to happen */
140     unsigned nevents = ff_kevent(kq, NULL, 0, events, MAX_EVENTS, NULL);
141     unsigned i;
142 
143     buf_len = sizeof(html) - 1;
144     buf_tmp = html;
145 
146     for (i = 0; i < nevents; ++i) {
147         struct kevent event = events[i];
148         int clientfd = (int)event.ident;
149 
150         /* Handle disconnect */
151         if (event.flags & EV_EOF) {
152             /* Simply close socket */
153             ff_close(clientfd);
154 #ifdef INET6
155         } else if (clientfd == sockfd || clientfd == sockfd6) {
156 #else
157         } else if (clientfd == sockfd) {
158 #endif
159             int available = (int)event.data;
160             do {
161                 int nclientfd = ff_accept(clientfd, NULL, NULL);
162                 if (nclientfd < 0) {
163                     printf("ff_accept failed:%d, %s\n", errno,
164                         strerror(errno));
165                     break;
166                 }
167 
168                 /* Add to event list */
169                 EV_SET(&kevSet, nclientfd, EVFILT_READ, EV_ADD, 0, 0, NULL);
170 
171                 if(ff_kevent(kq, &kevSet, 1, NULL, 0, NULL) < 0) {
172                     printf("ff_kevent error:%d, %s\n", errno,
173                         strerror(errno));
174                     return -1;
175                 }
176 
177                 available--;
178             } while (available);
179         } else if (event.filter == EVFILT_READ) {
180             char buf[256];
181             size_t readlen = ff_read(clientfd, buf, sizeof(buf));
182 #ifdef FSTACK_ZC_SEND
183             int ret = ff_zc_mbuf_get(&zc_buf, buf_len);
184             if (ret < 0) {
185                 printf("ff_zc_mbuf_get failed, len:%d, errno:%d, %s\n", buf_len, errno, strerror(errno));
186                 exit(1);
187             }
188 
189             /* APP can call ff_zc_mbuf_write multi times */
190             int len_part = 1440, off, to_write_len;
191             for (off = 0; off < buf_len;){
192                 to_write_len = (buf_len - off) > len_part ? len_part : (buf_len - off);
193                  ret = ff_zc_mbuf_write(&zc_buf, (const char *)buf_tmp + off, to_write_len);
194                  if (ret != to_write_len) {
195                      printf("ff_zc_mbuf_write failed, len:%d, errno:%d, %s\n", to_write_len, errno, strerror(errno));
196                      exit(1);
197                  }
198              off += to_write_len;
199             }
200 
201             /* Or call ff_zc_mbuf_write one time */
202             /*
203             if (ret != buf_len) {
204                 printf("ff_zc_mbuf_write failed, len:%d, errno:%d, %s\n", buf_len, errno, strerror(errno));
205                 exit(1);
206             }
207             */
208 
209             /* Simulate the application load */
210             int i, j = 0;
211             for (i = 0; i < 10000; i++){
212                 j++;
213             }
214             ff_write(clientfd, zc_buf.bsd_mbuf, buf_len);
215 #else
216             memcpy(html_buf, buf_tmp, buf_len);
217 
218             /* Simulate the application load */
219             int i, j = 0;
220             for (i = 0; i < 10000; i++){
221                 j++;
222             }
223 
224             ff_write(clientfd, html_buf, buf_len);
225 #endif
226         } else {
227             printf("unknown event: %8.8X\n", event.flags);
228         }
229 
230     }
231 }
232 
main(int argc,char * argv[])233 int main(int argc, char * argv[])
234 {
235     ff_init(argc, argv);
236 
237     assert((kq = ff_kqueue()) > 0);
238 
239     sockfd = ff_socket(AF_INET, SOCK_STREAM, 0);
240     if (sockfd < 0) {
241         printf("ff_socket failed, sockfd:%d, errno:%d, %s\n", sockfd, errno, strerror(errno));
242         exit(1);
243     }
244 
245     struct sockaddr_in my_addr;
246     bzero(&my_addr, sizeof(my_addr));
247     my_addr.sin_family = AF_INET;
248     my_addr.sin_port = htons(80);
249     my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
250 
251     int ret = ff_bind(sockfd, (struct linux_sockaddr *)&my_addr, sizeof(my_addr));
252     if (ret < 0) {
253         printf("ff_bind failed, sockfd:%d, errno:%d, %s\n", sockfd, errno, strerror(errno));
254         exit(1);
255     }
256 
257      ret = ff_listen(sockfd, MAX_EVENTS);
258     if (ret < 0) {
259         printf("ff_listen failed, sockfd:%d, errno:%d, %s\n", sockfd, errno, strerror(errno));
260         exit(1);
261     }
262 
263     EV_SET(&kevSet, sockfd, EVFILT_READ, EV_ADD, 0, MAX_EVENTS, NULL);
264     /* Update kqueue */
265     ff_kevent(kq, &kevSet, 1, NULL, 0, NULL);
266 
267 #ifdef INET6
268     sockfd6 = ff_socket(AF_INET6, SOCK_STREAM, 0);
269     if (sockfd6 < 0) {
270         printf("ff_socket failed, sockfd6:%d, errno:%d, %s\n", sockfd6, errno, strerror(errno));
271         exit(1);
272     }
273 
274     struct sockaddr_in6 my_addr6;
275     bzero(&my_addr6, sizeof(my_addr6));
276     my_addr6.sin6_family = AF_INET6;
277     my_addr6.sin6_port = htons(80);
278     my_addr6.sin6_addr = in6addr_any;
279 
280     ret = ff_bind(sockfd6, (struct linux_sockaddr *)&my_addr6, sizeof(my_addr6));
281     if (ret < 0) {
282         printf("ff_bind failed, sockfd6:%d, errno:%d, %s\n", sockfd6, errno, strerror(errno));
283         exit(1);
284     }
285 
286     ret = ff_listen(sockfd6, MAX_EVENTS);
287     if (ret < 0) {
288         printf("ff_listen failed, sockfd6:%d, errno:%d, %s\n", sockfd6, errno, strerror(errno));
289         exit(1);
290     }
291 
292     EV_SET(&kevSet, sockfd6, EVFILT_READ, EV_ADD, 0, MAX_EVENTS, NULL);
293     ff_kevent(kq, &kevSet, 1, NULL, 0, NULL);
294 #endif
295 
296     ff_run(loop, NULL);
297     return 0;
298 }
299