1 #include <stdio.h> 2 #include <sys/ioctl.h> 3 #include <stdlib.h> 4 #include <stdint.h> 5 #include <string.h> 6 #include <strings.h> 7 #include <sys/types.h> 8 #include <sys/socket.h> 9 #include <arpa/inet.h> 10 #include <errno.h> 11 #include <assert.h> 12 13 #include "ff_config.h" 14 #include "ff_api.h" 15 #include "ff_epoll.h" 16 17 18 #define MAX_EVENTS 512 19 20 struct epoll_event ev; 21 22 struct epoll_event events[MAX_EVENTS]; 23 struct kevent kqevents[MAX_EVENTS]; 24 25 int epfd; 26 int sockfd; 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: 439\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 int loop(void *arg) 61 { 62 /* Wait for events to happen */ 63 64 int nevents = ff_epoll_wait(epfd, events, MAX_EVENTS, 0); 65 int i; 66 67 for (i = 0; i < nevents; ++i) { 68 /* Handle new connect */ 69 if (events[i].data.fd == sockfd) { 70 int nclientfd = ff_accept(sockfd, NULL, NULL); 71 assert(nclientfd > 0); 72 /* Add to event list */ 73 ev.data.fd = nclientfd; 74 ev.events = EPOLLIN; 75 assert(ff_epoll_ctl(epfd, EPOLL_CTL_ADD, nclientfd, &ev) == 0); 76 //fprintf(stderr, "A new client connected to the server..., fd:%d\n", nclientfd); 77 } else { 78 if (events[i].events & EPOLLERR ) { 79 /* Simply close socket */ 80 ff_epoll_ctl(epfd, EPOLL_CTL_DEL, events[i].data.fd, NULL); 81 ff_close(events[i].data.fd); 82 //fprintf(stderr, "A client has left the server...,fd:%d\n", events[i].data.fd); 83 } else if (events[i].events & EPOLLIN) { 84 char buf[256]; 85 size_t readlen = ff_read( events[i].data.fd, buf, sizeof(buf)); 86 //fprintf(stderr, "bytes are available to read..., readlen:%d, fd:%d\n", readlen, events[i].data.fd); 87 if(readlen > 0){ 88 ff_write( events[i].data.fd, html, sizeof(html)); 89 } else { 90 ff_epoll_ctl(epfd, EPOLL_CTL_DEL, events[i].data.fd, NULL); 91 ff_close( events[i].data.fd); 92 //fprintf(stderr, "A client has left the server...,fd:%d\n", events[i].data.fd); 93 } 94 } else { 95 fprintf(stderr, "unknown event: %8.8X\n", events[i].events); 96 } 97 } 98 } 99 } 100 101 int main(int argc, char * argv[]) 102 { 103 char *conf; 104 if (argc < 2) { 105 conf = "./config.ini"; 106 } else { 107 conf = argv[1]; 108 } 109 110 ff_init(conf, argc, argv); 111 112 sockfd = ff_socket(AF_INET, SOCK_STREAM, 0); 113 printf("sockfd:%d\n", sockfd); 114 if (sockfd < 0) 115 printf("ff_socket failed\n"); 116 117 int on = 1; 118 ff_ioctl(sockfd, FIONBIO, &on); 119 120 struct sockaddr_in my_addr; 121 bzero(&my_addr, sizeof(my_addr)); 122 my_addr.sin_family = AF_INET; 123 my_addr.sin_port = htons(80); 124 my_addr.sin_addr.s_addr = htonl(INADDR_ANY); 125 126 int ret = ff_bind(sockfd, (struct linux_sockaddr *)&my_addr, sizeof(my_addr)); 127 if (ret < 0) { 128 printf("ff_bind failed\n"); 129 } 130 131 ret = ff_listen(sockfd, MAX_EVENTS); 132 if (ret < 0) { 133 printf("ff_listen failed\n"); 134 } 135 136 assert((epfd = ff_epoll_create(0)) > 0); 137 ev.data.fd = sockfd; 138 ev.events = EPOLLIN; 139 ff_epoll_ctl(epfd, EPOLL_CTL_ADD, sockfd, &ev); 140 ff_run(loop, NULL); 141 return 0; 142 } 143 144 145