void read_handler(aeEventLoop *el, int fd, void *privdata, int mask) { int err; int nread; (void) mask; char buf[BUF_SIZE]={0}; struct request *req = (struct request*)privdata; nread = read(fd, buf, BUF_SIZE); if (nread < 1) { request_free(req); aeDeleteFileEvent(el, fd, AE_WRITABLE); aeDeleteFileEvent(el, fd, AE_READABLE); close(fd); _clicount--; return; } else { request_append(req, buf, nread); err = request_parse(req); if (err == -1) { request_free(req); aeDeleteFileEvent(el, fd, AE_WRITABLE); aeDeleteFileEvent(el, fd, AE_READABLE); close(fd); _clicount--; return; } if (err == 1) { _process_cmd(fd, req); request_clean(req); } } }
static void connection_readable_cb(EV_P_ struct ev_io *watcher, int revents) { connection_t *c = get_ev_data(connection, watcher, read); char buf[BUFFER_CHUNK_SIZE]; if (EV_ERROR & revents) { connection_error(c, "Error reading on connection socket"); return; } size_t received = recv(c->fd, buf, BUFFER_CHUNK_SIZE, 0); ev_timer_again(c->loop, &c->timeout_watcher); if (received == -1) { /* error, closing connection */ connection_errno(c); return; } if (received == 0) { /* received 0 byte, read again next loop */ return; } trace(c->backend, buf, received); request_parse(c, buf, received); }
int main(/*int argc, char *argv[]*/) { INFO("Started\n"); int server_socket, client_socket, port, res, client_len, n; struct sockaddr_in srv_addr, client_addr; int iSetOption = 1; port = SRVPORT; server_socket = socket(AF_INET, SOCK_STREAM, 0); setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, (char*)&iSetOption, sizeof(iSetOption)); if (server_socket < 0) { ERROR("Error opening socket\n"); IFERROR(perror("")); } INFO("Made server socket\n"); memset((char *) &srv_addr, 0, sizeof(srv_addr)); srv_addr.sin_family = AF_INET; srv_addr.sin_port = htons(port); srv_addr.sin_addr.s_addr = INADDR_ANY; while ((res = bind(server_socket, (struct sockaddr *) &srv_addr, sizeof(srv_addr))) < 0) { ERROR("Error binding socket\n"); IFERROR(perror("")); } listen(server_socket, 5); INFO("Listening on port %d\n", port); client_len = sizeof(client_addr); if (chdir("content")) { ERROR("Could not chdir to the content directory\n"); IFERROR(perror("")); exit(1); } do { client_socket = accept(server_socket, (struct sockaddr *) &client_addr, (socklen_t *) &client_len); INFO("Accepted client socket\n"); if (client_socket < 0) { ERROR("Error on client accept\n"); IFERROR(perror("")); } request *req = request_new(); char line[MAXLEN]; while ((n = fd_readline(client_socket, line, MAXLEN)) > 0) { if (n == MAXLEN-1 && line[MAXLEN-1] != '\n') { WARN("Line length exceeded MAXLEN %d\n", MAXLEN); char c; int dropped = 0; while ((n = read(client_socket, &c, 1)) > 0) { dropped += 1; if (c == '\n') break; } WARN("Skipped to the next line, dropped %d characters\n", dropped); } if (is_crlf(line)) { // We've reached the end of the headers int left_to_read = request_get_content_length(req); int total_read = 0, len; if (left_to_read > 0) { DEBUG("There's %d chars of body to read\n", left_to_read); // There's a Content-Length so there must be a body req->body = malloc(sizeof(char) * (left_to_read+1)); len = MAXLEN < left_to_read ? MAXLEN : left_to_read; len += 1; while (left_to_read && (n = fd_readline(client_socket, line, len)) > 0) { DEBUG("Read %d characters of body: %s\n", n, line); strcpy(&req->body[total_read], line); total_read += n; left_to_read -= n; DEBUG("total_read: %d, left_to_read: %d\n", total_read, left_to_read); len = MAXLEN < left_to_read ? MAXLEN : left_to_read; } req->body[total_read+1] = '\0'; DEBUG("Done reading body in %d chars:\n", total_read); DEBUG("%s\n", req->body); respond(&req, client_socket); continue; } else { DEBUG("No body to read, generating response\n"); respond(&req, client_socket); continue; } } if (request_parse(req, line)) { WARN("An error occurred while parsing the previous line\n"); } } DEBUG("Done with this request! n = %d\n", n); } while (1); close(server_socket); close(client_socket); return 0; }
int main(int argc, char **args) { int httpd,client; struct sockaddr_in client_addr; socklen_t len = sizeof(client_addr); int epfd,nfds, i, fd, n, nread; struct epoll_event ev,events[MAX_CONNECT]; char buf[2048]; int ret = -1; signal(SIGPIPE, SIG_IGN); //set_log_file("./log.txt"); ret = chroot("web"); if (ret) { perror("chroot err"); //return -1; } on_exit(httpd_destory, (void *)&httpd); bzero(&client_addr,sizeof client_addr); if (0 > (httpd = mnet_tcp_server(HTTP_PORT))) { printf("start up server err\n"); return -1; } epfd = epoll_create(MAX_CONNECT); if (epfd == -1) { printf("err when epoll create\n"); return -1; } ev.data.fd = httpd; ev.events = EPOLLIN|EPOLLET;//监听读状态同时设置ET模式 epoll_ctl(epfd, EPOLL_CTL_ADD, httpd, &ev);//注册epoll事件 while(1) { nfds = epoll_wait(epfd, events, MAX_CONNECT, -1); if (nfds == -1) { printf("failed when epoll wait\n"); continue; } for (i = 0; i < nfds; i++) { fd = events[i].data.fd; if (fd == httpd) { while ((client = accept(httpd, (struct sockaddr *) &client_addr, (size_t *)&len)) > 0) { if (mnet_setnoblock(client)) { mlog_err("failed when set client nonlock"); continue; } ev.events = EPOLLIN | EPOLLET; ev.data.fd = client; if (epoll_ctl(epfd, EPOLL_CTL_ADD, client, &ev) == -1) { perror("epoll add client err"); continue; } mlog_info("accept fd : %d", client); } if (errno != EAGAIN && errno != ECONNABORTED && errno != EPROTO && errno != EINTR) perror("accept"); continue; } if (events[i].events & EPOLLIN) { n = 0; while ((nread = read(fd, buf + n, BUFSIZ-1)) > 0) //ET下可以读就一直读 { n += nread; } if (n == 0) { mlog_err("client: %d request over", fd); close(fd); continue; } buf[n] = 0; if (nread == -1 && errno != EAGAIN) { perror("read error"); } mlog_info("read fd : %d, req: %s", fd, buf); //recv_dump(fd); #if 0 ev.data.fd = fd; ev.events = events[i].events | EPOLLOUT; //MOD OUT if (epoll_ctl(epfd, EPOLL_CTL_MOD, fd, &ev) == -1) { perror("epoll_ctl: mod"); } #else do_request(request_parse(buf, len), fd); #endif } } } fail_label: close(httpd); return 0; }