int init_uds_server(const char* srv_name, struct uds_msg* msg) { memset(msg, 0, sizeof(struct uds_msg)); if((msg->sock = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1) { lmice_error_log("UDS socket create failed."); return 1; } msg->local_un.sun_family = AF_UNIX; strncpy(msg->local_un.sun_path, srv_name, strlen(srv_name)); unlink(srv_name); if(bind(msg->sock, (struct sockaddr*)&(msg->local_un), sizeof(msg->local_un)) == -1) { lmice_error_log("UDS socket bind failed."); return 1; } chmod(srv_name, 0666); if( make_socket_non_blocking(msg->sock) == -1) { lmice_error_log("UDS socket nonblock failed."); return 1; } return 0; }
CRoute_manager::CRoute_manager() { readconf("./conf.json"); if( (maintain_servfd = create_bind_socket("8080")) == -1 ) exit(-1); if(listen(maintain_servfd, 10) == -1) exit(-1); if( (info_fd = create_bind_socket("9090")) == -1 ) exit(-1); if(make_socket_non_blocking(info_fd) == -1) exit(1); if(listen(info_fd, SOMAXCONN) == -1) exit(-1); if( pthread_create(&mt_thread_id,NULL,maintain_thread,(void*)this) != 0 ) exit(-1); if( pthread_create(&info_thread_id,NULL,cellinfo_thread,(void*)this) != 0 ) exit(-1); // if( pthread_create(&thread_id,NULL,request_cellinfo_thread,(void*)this) != 0 ) // exit(-1); }
/** * @brief We have a notification on the listening socket, which means one or more incoming connections. * * @return */ static int new_connect(int listen_fd, int efd) { int infd; int ret = 0; infd = accept(listen_fd, NULL, 0); if (infd == -1) { printf("infd is -1\n"); if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) { /* We have processed all incoming connections. */ } else { DEBUG_ERROR("accept"); } return -1; } /* Make the incoming socket non-blocking and add it to the * list of fds to be monitored. */ ret = make_socket_non_blocking(infd); if (ret == -1) { DEBUG_ERROR("set none blocking error\n"); return ret; } return add2epoll(efd, EPOLLIN | EPOLLET, infd); }
/* accept pending connection requests */ void accept_connection() { int tfd; int ret; struct sockaddr_in addr; struct epoll_event ev; socklen_t len; for(;;) { tfd = accept(_listening_fd, (struct sockaddr*)&addr, &len); if(tfd == -1) { break; } else { make_socket_non_blocking(tfd); ev.events = EPOLLIN | EPOLLET; ev.data.fd = tfd; epoll_ctl(_efd, EPOLL_CTL_ADD, tfd, &ev); /* tell the client who he is * we use the fd number as a the client id */ do { ret = write(tfd, &tfd, sizeof tfd); }while(EAGAIN == ret || EWOULDBLOCK == ret); printf("connection established with %d\n", tfd); } } }
void acceptfun(struct schedule *s, void *ud) { int *lfd = (int *)ud; int *pcfd; struct sockaddr_in clientaddr; memset(&clientaddr, 0, sizeof(struct sockaddr_in)); socklen_t len = sizeof(clientaddr); while(1){ //printf("start accept..\n"); pcfd = (int *)malloc(sizeof(int)); *pcfd = accept(*lfd, (struct sockaddr *)&clientaddr, &len); //printf("%d\n", *pcfd); if(*pcfd == -1){ free(pcfd); if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) { coroutine_yield(s); } else { break; } } else { make_socket_non_blocking(*pcfd); int co = coroutine_new(s, dorequest, (void *)pcfd); } } }
/* create socket for listening incoming connections*/ int create_server_socket(unsigned short port, int nqueued) { int fd; struct sockaddr_in addr; fd = socket(AF_INET, SOCK_STREAM, 0); if(fd == -1) { perror(NULL); return E_NET_ERR; } addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(INADDR_ANY); addr.sin_port = htons(port); if(0 != bind(fd, (struct sockaddr *)&addr, sizeof(addr))) { perror(NULL); return E_NET_ERR; } make_socket_non_blocking(fd); if(listen(fd, nqueued) == -1) { perror(NULL); return E_NET_ERR; } return fd; }
struct cetimer * cetimer_create(unsigned int nextvalue, unsigned int interval, int wfd, int reconnwfd){ if(s_timer == NULL){ struct cetimer * timer = (struct cetimer *)malloc(sizeof(struct cetimer)); timer->tnexttime.tv_sec = nextvalue; timer->tinterval.tv_sec = interval; timer->timer.it_interval = timer->tinterval; timer->timer.it_value = timer->tnexttime; setitimer(ITIMER_REAL, &timer->timer, 0); timer->handler = checkstatus; make_socket_non_blocking(wfd); timer->wfd = wfd; make_socket_non_blocking(reconnwfd); timer->reconnwfd = reconnwfd; s_timer = timer; } return s_timer; }
int create_server(int port) { struct addrinfo hints; struct addrinfo *result, *rp; int s, sfd; char port_str[12] = {'\0'}; sprintf(port_str, "%d", port); memset(&hints, 0, sizeof (struct addrinfo)); hints.ai_family = AF_UNSPEC; /* Return IPv4 and IPv6 choices */ hints.ai_socktype = SOCK_STREAM; /* We want a TCP socket */ hints.ai_flags = AI_PASSIVE; /* All interfaces */ if((s = getaddrinfo(NULL, port_str, &hints, &result)) != 0) { fprintf(stderr, "getaddrinfo: %s\n", gai_strerror (s)); return -1; } for(rp = result; rp != NULL; rp = rp->ai_next) { if ((sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol)) == -1) continue; if(set_reuseaddr(sfd) == -1) abort(); if((s = bind(sfd, rp->ai_addr, rp->ai_addrlen)) == 0) break; close(sfd); } if(rp == NULL) { fprintf(stderr, "Could not bind\n"); return -1; } if ((s = make_socket_non_blocking(sfd)) == -1) return -1; if((s = listen(sfd, SOMAXCONN)) == -1) { perror("listen"); return -1; } freeaddrinfo(result); printf("Server started on port %d using fd %d\n", port, sfd); return sfd; }
struct epoll_event_handler* create_client_socket_handler(int client_socket_fd, int epoll_fd, char* backend_addr, char* backend_port_str) { make_socket_non_blocking(client_socket_fd); struct client_socket_event_data* closure = malloc(sizeof(struct client_socket_event_data)); struct epoll_event_handler* result = malloc(sizeof(struct epoll_event_handler)); result->fd = client_socket_fd; result->handle = handle_client_socket_event; result->closure = closure; closure->backend_handler = connect_to_backend(result, epoll_fd, backend_addr, backend_port_str); return result; }
int Serv::bind_and_listen(const char *serv_port) { int n; const int on = 1; struct addrinfo hints; struct addrinfo *res = NULL, *ressave = NULL; bzero(&hints, sizeof(struct addrinfo)); hints.ai_flags= AI_PASSIVE; hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; if((n = getaddrinfo(NULL, serv_port, &hints, &res)) != 0){ WARNING_LOG("tcp listen error for %s : %s", serv_port, gai_strerror(n)); } ressave = res; do{ listenfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); if(listenfd < 0){ continue; } if(setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0){ WARNING_LOG("setsockopt REUSEADDR error!"); break; } if(bind(listenfd, res->ai_addr, res->ai_addrlen) == 0){ break; } close(listenfd); }while( (res = res->ai_next) != NULL ); if(res == NULL){ WARNING_LOG("tcp listen error for %s", serv_port); return -1; } make_socket_non_blocking(listenfd); listen(listenfd, 1024); /* if(addrlenp){ *addrlenp = res->ai_addrlen; } */ freeaddrinfo(ressave); return listenfd; }
static void handle_accepting_connection(int server_fd) { sockaddr_in clientaddr; socklen_t clientlen = sizeof(clientaddr); int client_fd = accept(server_fd, (sockaddr*)&clientaddr, &clientlen); check_errors("accept", client_fd); char client_address[NI_MAXHOST], client_port[NI_MAXSERV]; int error_code = getnameinfo ((sockaddr*)&clientaddr, clientlen, client_address, sizeof client_address, client_port, sizeof client_port, NI_NUMERICHOST | NI_NUMERICSERV); make_socket_non_blocking(client_fd); connection_data *connection = allocate_connection(client_fd); connections++; if (global_accept_handler != NULL) global_accept_handler(error_code, connection, client_address, client_port); }
static void new_handle_accepting_connection(int server_fd, struct epoll_event &client_event, struct epoll_event &server_event) { sockaddr_in clientaddr; socklen_t clientlen = sizeof(clientaddr); int client_fd = accept(server_fd, (sockaddr*)&clientaddr, &clientlen); assert(client_fd > 0 || (client_fd == -1 && errno == EAGAIN)); if (client_fd > 0) { char client_address[NI_MAXHOST], client_port[NI_MAXSERV]; int error_code = getnameinfo ((sockaddr*)&clientaddr, clientlen, client_address, sizeof client_address, client_port, sizeof client_port, NI_NUMERICHOST | NI_NUMERICSERV); make_socket_non_blocking(client_fd); connection_data *connection = allocate_connection(client_fd); connections++; // epoll_event event; // event.events = EPOLLIN | EPOLLET; // event.data.ptr = connection; // int return_code = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, client_fd, &event); // assert(return_code >= 0); int return_code = epoll_ctl(epoll_fd, EPOLL_CTL_MOD, server_fd, &server_event); assert(return_code >= 0); if (global_accept_handler != NULL) global_accept_handler(error_code, connection, client_address, client_port); } }
int main() { int listenfd, optval = 1; int i; int port = 9500; struct sockaddr_in serveraddr; listenfd = socket(AF_INET, SOCK_STREAM, 0); setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (const void *)&optval , sizeof(int)); bzero((char *) &serveraddr, sizeof(serveraddr)); serveraddr.sin_family = AF_INET; serveraddr.sin_addr.s_addr = htonl(INADDR_ANY); serveraddr.sin_port = htons((unsigned short)port); bind(listenfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)); listen(listenfd, 1024); make_socket_non_blocking(listenfd); struct schedule * S = coroutine_open(); printf("start..\n"); int co1 = coroutine_new(S, acceptfun, (void *)&listenfd); printf("%d\n", S->cap); printf("%d\n", co1); for(i = 0; i < S->cap; i++) { if(coroutine_status(S, i)) { coroutine_resume(S,i); } if(i == S->cap - 1) i = -1; } coroutine_close(S); close(listenfd); return 0; }
int main(int argc, char *argv[]){ if (argc < 2) error("ERROR, no port provided\n"); int listen_socket; if ((listen_socket = create_and_bind_socket(argv[1])) == -1) error("Failed in create_and_bind_socket"); if (make_socket_non_blocking(listen_socket) == -1) error("Error in setting non_block"); if (listen(listen_socket,SOMAXCONN) == -1) error("Listen failed"); //THREADING INITIALIZATION struct sockaddr_in cli_addr; socklen_t addrlen; struct arg_struct { int conn_socket; pthread_key_t thr_id_key; int * thread_id; }; struct arg_struct args; pthread_t thread; int * thread_id; pthread_key_t thr_id_key; thread_id = (int * ) malloc(sizeof(int)); pthread_key_create(&thr_id_key, NULL); pthread_attr_t thread_attr; pthread_attr_init(&thread_attr); pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED); int epollfd, nfds, i, conn_socket; struct epoll_event event; struct epoll_event events[MAX_EVENTS]; if( (epollfd = epoll_create1 (0)) == -1) error ("epoll_create"); //typedef union epoll_data { // void *ptr; // int fd; // uint32_t u32; // uint64_t u64; //} epoll_data_t; // //struct epoll_event { // uint32_t events; /* Epoll events */ // epoll_data_t data; /* User data variable */ // }; event.events = EPOLLIN|EPOLLET; event.data.fd = listen_socket; if (epoll_ctl (epollfd, EPOLL_CTL_ADD, listen_socket, &event) == -1) error ("epoll_ctl fail"); int count = 0; while(1){ //printf("Waiting for connections[%d]....\n", count); if((nfds = epoll_wait(epollfd, events, MAX_EVENTS, -1)) == -1) //Returns number of events waiting error("epoll_pwait"); for (i = 0; i < nfds; i++){ count++; printf("Process connection [%d]\n", count); if (events[i].data.fd == listen_socket) { if((conn_socket = accept(listen_socket, (struct sockaddr *) &cli_addr, &addrlen)) == -1) error("accept failed"); if (make_socket_non_blocking(conn_socket) == -1) error("Error in setting non_block"); event.events = EPOLLIN|EPOLLET; event.data.fd = conn_socket; if ((epoll_ctl(epollfd, EPOLL_CTL_ADD, conn_socket, &event)) == -1) error("epoll_ctl: conn_socket failed"); } else{ args.conn_socket = events[i].data.fd; args.thread_id = thread_id; if(pthread_create (&thread, &thread_attr, talk_to_client, &args) != 0) error("Error creating a thread."); } } }//end of while printf("Exited while(1) ?!?!? \n"); pthread_exit(NULL); return 0; //should never get here }
int main (int argc, char *argv[]) { struct epoll_event event, *events; int sfd, s; int efd; /* Set up listening socket, 'listen_sock' (socket(), bind(), listen()) */ sfd = create_and_bind ("8888"); if (sfd == -1) abort (); s = make_socket_non_blocking (sfd); if (s == -1) { err_sys("socket error"); exit(1); } s = listen (sfd, SOMAXCONN); if (s == -1) { err_sys("listen"); exit(-1); } efd = epoll_create1 (0); if (efd == -1) { err_sys("epoll_create"); exit(-1); } event.data.fd = sfd; //event.events = EPOLLIN | EPOLLET; event.events = EPOLLIN; s = epoll_ctl (efd, EPOLL_CTL_ADD, sfd, &event); if (s == -1) { err_sys("epoll_ctl"); exit(-1); } /* Buffer where events are returned */ events = calloc (MAXEVENTS, sizeof event); /* The event loop */ while (1) { int n, i; n = epoll_wait (efd, events, MAXEVENTS, -1); for (i = 0; i < n; i++) { if ((events[i].events & EPOLLERR) || (events[i].events & EPOLLHUP) || (!(events[i].events & EPOLLIN))) { /* An error has occured on this fd, or the socket is not ready for reading (why were we notified then?) */ fprintf (stderr, "epoll error\n"); close (events[i].data.fd); continue; } else if (sfd == events[i].data.fd) { /* We have a notification on the listening socket, which means one or more incoming connections. */ while (1) { struct sockaddr in_addr; socklen_t in_len; int infd; char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV]; in_len = sizeof in_addr; infd = accept (sfd, &in_addr, &in_len); if (infd == -1) { if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) { /* We have processed all incoming connections. */ break; } else { perror ("accept"); break; } } s = getnameinfo (&in_addr, in_len, hbuf, sizeof hbuf, sbuf, sizeof sbuf, NI_NUMERICHOST | NI_NUMERICSERV); if (s == 0) { printf("Accepted connection on descriptor %d " "(host=%s, port=%s)\n", infd, hbuf, sbuf); } /* Make the incoming socket non-blocking and add it to the list of fds to monitor. */ s = make_socket_non_blocking (infd); if (s == -1) abort (); event.data.fd = infd; //event.events = EPOLLIN | EPOLLET; event.events = EPOLLIN; s = epoll_ctl (efd, EPOLL_CTL_ADD, infd, &event); if (s == -1) { err_sys("epoll_ctl"); } } continue; } else { /* We have data on the fd waiting to be read. Read and display it. We must read whatever data is available completely, as we are running in edge-triggered mode and won't get a notification again for the same data. */ int done = 0; while (1) { ssize_t count; char buf[2]; count = read (events[i].data.fd, buf, sizeof buf); if (count == -1) { /* If errno == EAGAIN, that means we have read all data. So go back to the main loop. */ if (errno != EAGAIN) { perror ("read"); done = 1; } break; } else if (count == 0) { /* End of file. The remote has closed the connection. */ done = 1; break; } /* Write the buffer to standard output */ s = write (1, buf, count); if (s == -1) { err_sys("write"); } } if (done) { printf ("Closed connection on descriptor %d\n", events[i].data.fd); /* Closing the descriptor will make epoll remove it from the set of descriptors which are monitored. */ close (events[i].data.fd); } } } } return 0; }
int main(int argc, const char** argv) { setvbuf(stdout, NULL, _IONBF, 0); int portnum = 9090; if (argc >= 2) { portnum = atoi(argv[1]); } printf("Serving on port %d\n", portnum); int listener_sockfd = listen_inet_socket(portnum); make_socket_non_blocking(listener_sockfd); int epollfd = epoll_create1(0); if (epollfd < 0) { perror_die("epoll_create1"); } struct epoll_event accept_event; accept_event.data.fd = listener_sockfd; accept_event.events = EPOLLIN; if (epoll_ctl(epollfd, EPOLL_CTL_ADD, listener_sockfd, &accept_event) < 0) { perror_die("epoll_ctl EPOLL_CTL_ADD"); } struct epoll_event* events = calloc(MAXFDS, sizeof(struct epoll_event)); if (events == NULL) { die("Unable to allocate memory for epoll_events"); } while (1) { int nready = epoll_wait(epollfd, events, MAXFDS, -1); for (int i = 0; i < nready; i++) { if (events[i].events & EPOLLERR) { perror_die("epoll_wait returned EPOLLERR"); } if (events[i].data.fd == listener_sockfd) { // The listening socket is ready; this means a new peer is connecting. struct sockaddr_in peer_addr; socklen_t peer_addr_len = sizeof(peer_addr); int newsockfd = accept(listener_sockfd, (struct sockaddr*)&peer_addr, &peer_addr_len); if (newsockfd < 0) { if (errno == EAGAIN || errno == EWOULDBLOCK) { // This can happen due to the nonblocking socket mode; in this // case don't do anything, but print a notice (since these events // are extremely rare and interesting to observe...) printf("accept returned EAGAIN or EWOULDBLOCK\n"); } else { perror_die("accept"); } } else { make_socket_non_blocking(newsockfd); if (newsockfd >= MAXFDS) { die("socket fd (%d) >= MAXFDS (%d)", newsockfd, MAXFDS); } fd_status_t status = on_peer_connected(newsockfd, &peer_addr, peer_addr_len); struct epoll_event event = {0}; event.data.fd = newsockfd; if (status.want_read) { event.events |= EPOLLIN; } if (status.want_write) { event.events |= EPOLLOUT; } if (epoll_ctl(epollfd, EPOLL_CTL_ADD, newsockfd, &event) < 0) { perror_die("epoll_ctl EPOLL_CTL_ADD"); } } } else { // A peer socket is ready. if (events[i].events & EPOLLIN) { // Ready for reading. int fd = events[i].data.fd; fd_status_t status = on_peer_ready_recv(fd); struct epoll_event event = {0}; event.data.fd = fd; if (status.want_read) { event.events |= EPOLLIN; } if (status.want_write) { event.events |= EPOLLOUT; } if (event.events == 0) { printf("socket %d closing\n", fd); if (epoll_ctl(epollfd, EPOLL_CTL_DEL, fd, NULL) < 0) { perror_die("epoll_ctl EPOLL_CTL_DEL"); } close(fd); } else if (epoll_ctl(epollfd, EPOLL_CTL_MOD, fd, &event) < 0) { perror_die("epoll_ctl EPOLL_CTL_MOD"); } } else if (events[i].events & EPOLLOUT) { // Ready for writing. int fd = events[i].data.fd; fd_status_t status = on_peer_ready_send(fd); struct epoll_event event = {0}; event.data.fd = fd; if (status.want_read) { event.events |= EPOLLIN; } if (status.want_write) { event.events |= EPOLLOUT; } if (event.events == 0) { printf("socket %d closing\n", fd); if (epoll_ctl(epollfd, EPOLL_CTL_DEL, fd, NULL) < 0) { perror_die("epoll_ctl EPOLL_CTL_DEL"); } close(fd); } else if (epoll_ctl(epollfd, EPOLL_CTL_MOD, fd, &event) < 0) { perror_die("epoll_ctl EPOLL_CTL_MOD"); } } } } } return 0; }
int main(int argc, char *argv[]) { int sfd, s; int efd; int so_rcvbuf = 0; int verbose = 0; struct epoll_event event; struct epoll_event *events; struct edata { int fd; int content_length; int content_offset; char *header_buf; int header_off; int header_max; }; if (argc < 2 || argc > 3) { fprintf(stderr, "Usage: %s [port] [rcvbuf]\n", argv[0]); exit(EXIT_FAILURE); } sfd = create_and_bind(argv[1]); if (sfd == -1) abort(); if (argc == 3) so_rcvbuf = atoi(argv[2]); s = make_socket_non_blocking(sfd); if (s == -1) abort(); s = listen(sfd, SOMAXCONN); if (s == -1) { perror("listen"); abort(); } efd = epoll_create1(0); if (efd == -1) { perror("epoll_create"); abort(); } struct edata *ed = malloc(sizeof(*ed)); ed->fd = sfd; ed->header_buf = 0; event.data.ptr = ed; event.events = EPOLLIN | EPOLLET; s = epoll_ctl(efd, EPOLL_CTL_ADD, sfd, &event); if (s == -1) { perror("epoll_ctl"); abort(); } /* Buffer where events are returned */ events = calloc(MAXEVENTS, sizeof event); /* The event loop */ while (1) { int n, i; n = epoll_wait(efd, events, MAXEVENTS, -1); for (i = 0; i < n; i++) { struct edata *ed = events[i].data.ptr; int fd = ed->fd; if ((events[i].events & EPOLLERR) || (events[i].events & EPOLLHUP) || (!(events[i].events & EPOLLIN))) { fprintf(stderr, "epoll error\n"); s = epoll_ctl(efd, EPOLL_CTL_DEL, fd, 0); if (s == -1) { perror("epoll_ctl"); abort(); } close(fd); free(ed); continue; } else if (sfd == fd) { while (1) { struct sockaddr in_addr; socklen_t in_len; int infd; char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV]; in_len = sizeof in_addr; infd = accept(sfd, &in_addr, &in_len); if (infd == -1) { if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) { break; } else { perror("accept"); break; } } s = getnameinfo(&in_addr, in_len, hbuf, sizeof hbuf, sbuf, sizeof sbuf, NI_NUMERICHOST | NI_NUMERICSERV); if (s == 0) { if (verbose) printf("Accepted connection on descriptor %d " "(host=%s, port=%s)\n", infd, hbuf, sbuf); } if (so_rcvbuf) if (setsockopt(infd, SOL_SOCKET, SO_RCVBUF, &so_rcvbuf, sizeof(so_rcvbuf))) { perror("setsocopt"); abort(); } s = make_socket_non_blocking(infd); if (s == -1) abort(); ed = malloc(sizeof(*ed)); ed->fd = infd; ed->content_length = -1; ed->header_max = 999; ed->header_buf = malloc(ed->header_max + 1); ed->header_off = 0; event.data.ptr = ed; event.events = EPOLLIN | EPOLLET; s = epoll_ctl(efd, EPOLL_CTL_ADD, infd, &event); if (s == -1) { perror("epoll_ctl"); abort(); } } continue; } else { int done = 0; while (1) { ssize_t count; char buf[32768]; if (ed->content_length == -1) { count = read(fd, ed->header_buf + ed->header_off, ed->header_max - ed->header_off); } else { count = read(fd, buf, sizeof buf); } if (count == -1) { if (errno != EAGAIN) { perror("read"); done = 1; } break; } else if (count == 0) { done = 1; break; } else { if (ed->content_length == -1) { const char *cp2; ed->header_off += count; ed->header_buf[ed->header_off] = '\0'; cp2 = strstr(ed->header_buf, "\r\n\r\n"); if (cp2) cp2 += 4; else if (!cp2) { cp2 = strstr(ed->header_buf, "\n\n"); if (cp2) cp2 += 2; } if (cp2) /* complete header? */ { const char *cp1 = strstr(ed->header_buf, "\nContent-Length:"); if (!cp1) cp1 = strstr(ed->header_buf, "\nContent-length:"); if (cp1 && cp1 < cp2) ed->content_length = atoi(cp1 + 16); else ed->content_length = 0; ed->content_offset = ed->header_off - (cp2 - ed->header_buf); if (ed->content_offset == 0) { if (strstr(ed->header_buf, "\nExpect: 100-continue")) { char buf[64]; strcpy(buf, "HTTP/1.1 100 Continue\r\n\r\n"); write(fd, buf, strlen(buf)); } } if (verbose) printf("complete header length=%d\n", ed->content_length); } else { if (ed->header_off == ed->header_max) { printf("Too big header\n"); done = 1; } } } else { ed->content_offset += count; } if (ed->content_length != -1 && ed->content_offset == ed->content_length) { if (verbose) printf("Got all content %d\n", ed->content_length); done = 1; } } } if (done) { if (verbose) printf("Closing descriptor %d\n", fd); char buf[1000]; strcpy(buf, "HTTP/1.0 200 OK\r\n" "Content-Length: 0\r\n" "Connection: Close\r\n" "\r\n"); write(fd, buf, strlen(buf)); s = epoll_ctl(efd, EPOLL_CTL_DEL, fd, 0); if (s == -1) { perror("epoll_ctl"); abort(); } close(fd); free(ed->header_buf); free(ed); } } } } free(events); close(sfd); return EXIT_SUCCESS; }
static void accept_handler(connections_head_t *head, connection_t *conn) { struct sockaddr in_addr; socklen_t in_len; int infd, lsfd; int ret; connection_t *new_conn; struct epoll_event event; char hbuf[64], sbuf[64]; /* We have a notification on the listening socket, which * means one or more incoming connections. */ while (1) { in_len = sizeof(struct sockaddr); lsfd = conn->fd; infd = accept(lsfd, &in_addr, &in_len); if (-1 == infd) { if ((EAGAIN == errno) || (EWOULDBLOCK == errno)) { /* We have processed all incoming * connections. */ break; } else { ERROR_MSG("accept"); break; } } ret = getnameinfo(&in_addr, in_len, hbuf, sizeof hbuf, sbuf, sizeof sbuf, NI_NUMERICHOST | NI_NUMERICSERV); if (0 == ret) { printf("Accepted connection on descriptor %d " "(host=%s, port=%s)\n", infd, hbuf, sbuf); } /* Make the incoming socket non-blocking and add it * to the list of fds to monitor */ ret = make_socket_non_blocking(infd); if (-1 == ret) { ERROR_MSG("make_socket_non_blocking\n"); abort(); } new_conn = get_connection(head); if (NULL == new_conn) { ERROR_MSG("get_connection\n"); abort(); } new_conn->fd = infd; new_conn->ssl = NULL; //new_conn->handler = rdwr_handler; new_conn->handler = do_ssl_accept; event.data.ptr = new_conn; event.events = EPOLLIN | EPOLLET; ret = epoll_ctl(head->epfd, EPOLL_CTL_ADD, infd, &event); if (-1 == ret) { ERROR_MSG("epoll_ctl\n"); abort(); } } }
int main(int argc, char *argv[]) { if (argc != 2) { print_err("Arguments failure"); } pid_t main_pid = fork(); switch(main_pid) { case 0: break; case -1: print_err("Can't fork main"); default: exit(0); } if(setsid()<0) { print_err("Can't start new session"); } pid_t nsession_pid = fork(); switch(nsession_pid) { case 0: break; case -1: print_err("Can't fork from deamon"); default: return 0; } pid_t daemon_pid = getpid(); int tmp_fd = open("/tmp/netsh.pid", O_WRONLY | O_CREAT); char* buf = new char[64]; int digits = sprintf(buf, "%d\n", daemon_pid); ssize_t written_count = write(tmp_fd, buf, digits); if (written_count == -1) { close(tmp_fd); print_err("Failed to write pid to file"); } close(tmp_fd); //Done pre part const int epoll_size = 32; struct epoll_event event; struct epoll_event *events; //prepare socket int socket_fd = create_and_bind(argv[1]); make_socket_non_blocking(socket_fd); if (listen(socket_fd, SOMAXCONN) == -1) { print_err("Can't setup listener"); } //Setup epoll int epoll_fd = epoll_create1(0); if (epoll_fd == -1) { print_err("Can't create epoll"); } event.data.fd = socket_fd; event.events = EPOLLIN | EPOLLET; int ectl_status = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, socket_fd, &event); if (ectl_status == -1) { print_err("Can't register fd in epoll"); } events = calloc(epoll_size, sizeof(event)); while (1) { int n, i; n = epoll_wait (epoll_fd, events, epoll_size, -1); for (i = 0; i < n; i++) { if ((events[i].events & EPOLLERR) || (events[i].events & EPOLLHUP) || (!(events[i].events & EPOLLIN))) { close (events[i].data.fd); continue; } else if (socket_fd == events[i].data.fd) { while (1) { struct sockaddr in_addr; socklen_t in_len; int infd; char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV]; in_len = sizeof in_addr; infd = accept (socket_fd, &in_addr, &in_len); if (infd == -1) { if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) { break; } else { perror ("Can't accept"); break; } } int unblock_status = make_socket_non_blocking (infd); if (unblock_status == -1) print_err("Can't unblock socket"); event.data.fd = infd; event.events = EPOLLIN | EPOLLET; int epc_status = epoll_ctl (epoll_fd, EPOLL_CTL_ADD, infd, &event); if (epc_status == -1) { print_err("Can't add flags"); } } continue; } else if (events[i].events == EPOLLIN) { int done = 0; read_and_exec(events[i].data.fd); if (1) { close (events[i].data.fd); } } else if (events[i].events == EPOLLOUT) { } } } return 0; }
int main(int argc, char *argv[]) { printf("%s", "start\n"); int listen_fd; int rcode; struct epoll_event *events; if (argc != 2) { fprintf(stderr, "usage: %s [port]\n", argv[0]); exit(EXIT_FAILURE); } struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_handler = SIG_IGN; sa.sa_flags = 0; if (sigaction(SIGPIPE, &sa, NULL)) { printf("ignore SIGPIPE\n"); } struct sockaddr_in client_addr; socklen_t client_len = 1; memset(&client_addr, 0, sizeof(struct sockaddr_in)); /* create and bind the port, and then set the socket to non blocking mode */ listen_fd = open_listenfd(atoi(argv[1])); debug("listen fd = %d", listen_fd); rcode = make_socket_non_blocking(listen_fd); if (rcode == -1) { log_err("error when making socket non blocking"); abort(); } /* create epoll event */ int efd = epoll_create1(0); if (efd == -1) { log_err("epoll_create"); abort(); } struct epoll_event event; events = (struct epoll_event *)malloc(sizeof(struct epoll_event) * MAXEVENTS); http_request_t *request = (http_request_t *)malloc(sizeof(http_request_t)); http_request_init(request, listen_fd); event.data.ptr = (void *)request; event.events = EPOLLIN | EPOLLET; /* register the listen event */ rcode = epoll_ctl(efd, EPOLL_CTL_ADD, listen_fd, &event); if (rcode == -1) { perror("epoll_ctl"); abort(); } threadpool_t *tp = threadpool_init(NUM_OF_THREADS); /* event loop */ while (1) { int n = epoll_wait(efd, events, MAXEVENTS, -1); /* process each incoming IO event */ int i; for (i = 0; i < n; i++) { http_request_t *r = (http_request_t *)events[i].data.ptr; int fd = r->fd; debug("event fd = %d", fd); if (fd == listen_fd) { /* incoming connection event */ while (1) { int client_fd; debug("waiting for accept"); client_fd = accept(listen_fd, (struct sockaddr *)&client_addr, &client_len); if (client_fd == -1) { if (errno == EAGAIN || errno == EWOULDBLOCK) { // we have already processed the incoming connection debug("incoming connection processed\n"); break; } else { log_err("error occured when accepting connection\n"); break; } } rcode = make_socket_non_blocking(client_fd); if (rcode == -1) { if (errno == EAGAIN || errno == EWOULDBLOCK) // we have already processed the incoming connection break; log_err("fail to accept the connection\n"); break; } debug("new connection fd %d", client_fd); http_request_t *request = (http_request_t *)malloc(sizeof(http_request_t)); http_request_init(request, client_fd); event.data.ptr = (void *)request; event.events = EPOLLIN | EPOLLET; /* add the new event into epoll */ rcode = epoll_ctl(efd, EPOLL_CTL_ADD, client_fd, &event); if (rcode == - 1) { log_err("fail in epoll_ctl in epoll_wait"); abort(); } } debug("end accept"); } else if ((events[i].events & EPOLLERR) || (events[i].events & EPOLLHUP) || (!(events[i].events & EPOLLIN))) { /* an error has occured on this fd, or the socket is not ready for reading */ log_err("error events: %d", events[i].events); if (events[i].events & EPOLLERR) log_err("EPOLLERR"); if (events[i].events & EPOLLHUP) log_err("EPOLLHUP"); if (!(events[i].events & EPOLLIN)) log_err("EPOLLIN"); close(fd); continue; } else { /* incoming data read event */ /* add the event to the thread pool list */ threadpool_add(tp, handle_http, events[i].data.ptr); debug("thread count: %d", tp->thread_count); debug("thread queue size: %d", tp->queue_size); } } } threadpool_destroy(tp); return 0; }
void* sock_boot (void *v_options) { int sfd, s; int efd; struct epoll_event event; struct epoll_event *events; s_options* options = (s_options *) v_options; sfd = create_and_bind (options->port); if (sfd == -1) abort (); s = make_socket_non_blocking (sfd); if (s == -1) abort (); s = listen (sfd, SOMAXCONN); if (s == -1) { perror ("listen"); abort (); } efd = epoll_create (1); if (efd == -1) { perror ("epoll_create"); abort (); } event.data.fd = sfd; event.events = EPOLLIN | EPOLLET; s = epoll_ctl (efd, EPOLL_CTL_ADD, sfd, &event); if (s == -1) { perror ("epoll_ctl"); abort (); } /* Buffer where events are returned */ events = calloc (MAXEVENTS, sizeof event); /* The event loop */ while (1) { int n, i; n = epoll_wait (efd, events, MAXEVENTS, -1); for (i = 0; i < n; i++) { if ((events[i].events & EPOLLERR) || (events[i].events & EPOLLHUP) || (!(events[i].events & EPOLLIN))) { /* An error has occured on this fd, or the socket is not ready for reading (why were we notified then?) */ fprintf (stderr, "epoll error\n"); close (events[i].data.fd); continue; } else if (sfd == events[i].data.fd) { /* We have a notification on the listening socket, which means one or more incoming connections. */ while (1) { struct sockaddr in_addr; socklen_t in_len; int infd; char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV]; in_len = sizeof in_addr; infd = accept (sfd, &in_addr, &in_len); if (infd == -1) { if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) { /* We have processed all incoming connections. */ break; } else { perror ("accept"); break; } } s = getnameinfo (&in_addr, in_len, hbuf, sizeof hbuf, sbuf, sizeof sbuf, NI_NUMERICHOST | NI_NUMERICSERV); if (s == 0) { printf("Accepted connection on descriptor %d " "(host=%s, port=%s)\n", infd, hbuf, sbuf); } /* Make the incoming socket non-blocking and add it to the list of fds to monitor. */ s = make_socket_non_blocking (infd); if (s == -1) abort (); event.data.fd = infd; event.events = EPOLLIN | EPOLLET; s = epoll_ctl (efd, EPOLL_CTL_ADD, infd, &event); if (s == -1) { perror ("epoll_ctl"); abort (); } } continue; } else { /* We have data on the fd waiting to be read. Read and display it. We must read whatever data is available completely, as we are running in edge-triggered mode and won't get a notification again for the same data. */ int done = 0; while (1) { ssize_t count; char buf[512]; count = read (events[i].data.fd, buf, sizeof buf); if (count == -1) { /* If errno == EAGAIN, that means we have read all data. So go back to the main loop. */ if (errno != EAGAIN) { perror ("read"); done = 1; } break; } else if (count == 0) { /* End of file. The remote has closed the connection. */ done = 1; break; } char c_payload_size[9]; memcpy(c_payload_size,&buf[0],8); c_payload_size[8] = '\0'; char *e; unsigned long int payload_size = strtoul(c_payload_size,&e,16); clients_data[i].payload_size = payload_size; memcpy(clients_data[i].buffer,&buf[8],payload_size); t_split *directives = ksplit(clients_data[i].buffer,"\x0d\x0a"); int j; for (j=0; j < directives->count; ++j) { memcpy(&received_data_queue[received_data_queue_tail++],directives->splited_ary[j],payload_size); if (received_data_queue_tail > MAX_RECEIVE_QUEUE) received_data_queue_tail = 0; //strcpy(clients_data[i].buffer,&buf[8]); #ifdef DEBUG //printf("payload_size:[%d] | ",payload_size); //printf("clients_data[%d].payload_size:[%lu] | ",i,payload_size); printf("clients_data[%d].buffer:[%s]\n",i,directives->splited_ary[j]); #endif } } if (done) { printf ("Closed connection on descriptor %d\n", events[i].data.fd); /* Closing the descriptor will make epoll remove it from the set of descriptors which are monitored. */ close (events[i].data.fd); } } } } free (events); close (sfd); return EXIT_SUCCESS; }
int main (int argc, char *argv[]) { /* initialization code */ cvect_t *dyn_vect = ccache_init(); assert(dyn_vect); int sfd, s; int efd; struct epoll_event event; struct epoll_event *events; char buf[BUFFER_SIZE]; char localbuf[BUFFER_SIZE]; if (argc != 2) { fprintf (stderr, "Usage: %s [port]\n", argv[0]); exit (EXIT_FAILURE); } sfd = create_and_bind (argv[1]); if (sfd == -1) abort (); s = make_socket_non_blocking (sfd); if (s == -1) abort (); s = listen (sfd, SOMAXCONN); if (s == -1) { perror ("listen"); abort (); } efd = epoll_create1 (0); if (efd == -1) { perror ("epoll_create"); abort (); } event.data.fd = sfd; event.events = EPOLLIN | EPOLLET; s = epoll_ctl (efd, EPOLL_CTL_ADD, sfd, &event); if (s == -1) { perror ("epoll_ctl"); abort (); } /* Buffer where events are returned */ events = calloc (MAXEVENTS, sizeof event); /* The event loop */ while (1) { int n, i; n = epoll_wait (efd, events, MAXEVENTS, -1); for (i = 0; i < n; i++) { if ((events[i].events & EPOLLERR) || (events[i].events & EPOLLHUP) || (!(events[i].events & EPOLLIN))) { /* An error has occured on this fd, or the socket is not ready for reading (why were we notified then?) */ fprintf (stderr, "epoll error\n"); close (events[i].data.fd); continue; } else if (sfd == events[i].data.fd) { /* We have a notification on the listening socket, which means one or more incoming connections. */ while (1) { struct sockaddr in_addr; socklen_t in_len; int infd; char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV]; in_len = sizeof in_addr; infd = accept (sfd, &in_addr, &in_len); if (infd == -1) { if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) { /* We have processed all incoming connections. */ break; } else { perror ("accept"); break; } } s = getnameinfo (&in_addr, in_len, hbuf, sizeof hbuf, sbuf, sizeof sbuf, NI_NUMERICHOST | NI_NUMERICSERV); if (s == 0) { printf("Accepted connection on descriptor %d " "(host=%s, port=%s)\n", infd, hbuf, sbuf); } /* Make the incoming socket non-blocking and add it to the list of fds to monitor. */ s = make_socket_non_blocking (infd); if (s == -1) abort (); event.data.fd = infd; event.events = EPOLLIN | EPOLLET; s = epoll_ctl (efd, EPOLL_CTL_ADD, infd, &event); if (s == -1) { perror ("epoll_ctl"); abort (); } } continue; } else { /* We have data on the fd waiting to be read. Read and process it. We must read whatever data is available completely, as we are running in edge-triggered mode and won't get a notification again for the same data. */ int done = 0; while (1) { ssize_t count; bzero(buf,BUFFER_SIZE); //zero out the buffer every time count = read (events[i].data.fd, buf, sizeof buf); if (count == -1) { /* If errno == EAGAIN, that means we have read all data. So go back to the main loop. */ if (errno != EAGAIN) { perror ("read"); done = 1; } break; } else if (count == 0) { /* End of file. The remote has closed the connection. */ done = 1; break; } /* Process the buffered request and write the results to the output */ buf[strlen(buf)-1] = '\0'; //remove trailing newline /* Make sure this request is complete - can do special handling based on creq_type then */ strcpy(localbuf, buf); ccmd_t type = get_creq_type(localbuf); strcpy(localbuf, buf); if(type == CSET) { creq_t *creq = (creq_t *) malloc(sizeof(creq_t)); creq = ccache_req_parse(buf); //now process that actual buffer /* Write Header and Footer to socket */ printf("before header: %s, strlen: %i\n", buf, strlen(creq->resp.header)); if((s = write (events[i].data.fd, creq->resp.header, strlen(creq->resp.header))) == -1) goto write_error; if(creq->resp.errcode == RERROR || creq->resp.errcode == 0){ if((s = write (events[i].data.fd, creq->resp.footer, strlen(creq->resp.footer))) == -1) goto write_error; } } /* CGET */ else if(type == CGET){ /* split multiple requests into single requests and process them */ char * pch; int counter = 0; pch = strtok(localbuf, " "); while(pch != NULL){ if(counter != 0){ /* formulate this new request and then skip the parsing step */ creq_t *creq = (creq_t *) malloc(sizeof(creq_t)); strcpy(creq->key, pch); creq->type = CGET; creq = ccache_get(creq); /* Write Header and Footer to socket */ //printf("before header: %s, strlen: %i\n", buf, strlen(creq->resp.header)); if((s = write (events[i].data.fd, creq->resp.header, strlen(creq->resp.header))) == -1) goto write_error; if(creq->resp.errcode == RERROR || creq->resp.errcode == 0){ if((s = write (events[i].data.fd, creq->resp.footer, strlen(creq->resp.footer))) == -1) goto write_error; } } pch = strtok(NULL, " "); counter++; } /* now that we're done transmitting all the CGET reqs - transmit END */ if((s = write (events[i].data.fd, "END\r\n", strlen("END\r\n"))) == -1) goto write_error; } else if(type == CDELETE || type == INVALID){ creq_t *creq = (creq_t *) malloc(sizeof(creq_t)); creq = ccache_req_parse(buf); //now process that actual buffer /* Write Header and Footer to socket */ printf("before header: %s, strlen: %i\n", buf, strlen(creq->resp.header)); if((s = write (events[i].data.fd, creq->resp.header, strlen(creq->resp.header))) == -1) goto write_error; if(creq->resp.errcode == RERROR || creq->resp.errcode == 0){ if((s = write (events[i].data.fd, creq->resp.footer, strlen(creq->resp.footer))) == -1) goto write_error; } /* cleanup from delete */ free(creq); } else{ printf("error! exiting\n"); exit(1); } } if (done) { printf ("Closed connection on descriptor %d\n", events[i].data.fd); /* Closing the descriptor will make epoll remove it from the set of descriptors which are monitored. */ close (events[i].data.fd); } } } } free (events); close (sfd); return EXIT_SUCCESS; write_error: if (s == -1) { perror ("write"); abort (); } return -1; }
void str_cli(FILE *fp, int sockfd) { char sendline[MAXLINE], recvline[MAXLINE]; int ret, n, i; size_t len; int efd; struct epoll_event event; struct epoll_event events[2]; // Same with epoll_create(), except the argument size is ignored. if ((efd = epoll_create1(0)) == -1) { perror ("epoll_create"); exit(EXIT_FAILURE); } if(make_socket_non_blocking (fileno(stdin)) == -1) exit(EXIT_FAILURE); if(make_socket_non_blocking (sockfd) == -1) exit(EXIT_FAILURE); event.data.fd = fileno(stdin); // stdin event.events = EPOLLIN;// | EPOLLET; if (epoll_ctl(efd, EPOLL_CTL_ADD, fileno(stdin), &event) == -1) { perror("epoll_ctl"); exit(EXIT_FAILURE); } event.data.fd = sockfd; // stdin event.events = EPOLLIN;// | EPOLLET; if (epoll_ctl(efd, EPOLL_CTL_ADD, sockfd, &event) == -1) { perror("epoll_ctl"); exit(EXIT_FAILURE); } for (;;) { n = epoll_wait (efd, events, 2, -1); // only stdin+sockfd for (i = 0; i < n; i++) { if ((events[i].events & EPOLLERR) || (events[i].events & EPOLLHUP) || (!(events[i].events & EPOLLIN))) { /* An error has occured on this fd, or the socket is not ready for reading (why were we notified then?) */ fprintf (stderr, "epoll error\n"); close (events[i].data.fd); exit(EXIT_FAILURE); } if (sockfd == events[i].data.fd) { // socket is readable. ret = readline(sockfd, recvline, MAXLINE); if (ret == 0) { fprintf(stderr, "str_cli: server terminated prematurely\n"); exit(EXIT_FAILURE); } else if (ret < 0) { fprintf(stderr, "str_cli error\n"); exit(EXIT_FAILURE); } fputs("socket: ", stdout); if (fputs(recvline, stdout) == EOF) { fprintf(stderr, "fputs error\n"); exit(EXIT_FAILURE); } } if (fileno(stdin) == events[i].data.fd) { // input is readable. if (fgets(sendline, MAXLINE, fp) == NULL) { if (ferror(fp)) { // stream errors. fprintf(stderr, "fgets error\n"); exit(EXIT_FAILURE); } else { // end of file. return; } } fputs("stdin : ", stdout); if (fputs(sendline, stdout) == EOF) { fprintf(stderr, "fputs error\n"); exit(EXIT_FAILURE); } len = strlen(sendline); if (writen(sockfd, sendline, len) != len) { fprintf(stderr, "writen error\n"); exit(EXIT_FAILURE); } } } } }
int main (int argc, char *argv[]) { struct epoll_event event, *events; int sfd, s; int efd; struct stat st; char *fifo = "event.fifo"; if (lstat (fifo, &st) == 0) { if ((st.st_mode & S_IFMT) == S_IFREG) { errno = EEXIST; err_sys("lstat"); exit (1); } } unlink (fifo); if (mkfifo (fifo, 0600) == -1) { err_sys("mkfifo"); exit (1); } /* Linux pipes are broken, we need O_RDWR instead of O_RDONLY */ sfd = open (fifo, O_RDWR | O_NONBLOCK, 0); if (sfd == -1) { err_sys("open"); exit (1); } s = make_socket_non_blocking (sfd); if (s == -1) { err_sys("socket error"); exit(1); } efd = epoll_create1 (0); if (efd == -1) { err_sys("epoll_create"); exit(1); } event.data.fd = sfd; event.events = EPOLLIN | EPOLLET; s = epoll_ctl (efd, EPOLL_CTL_ADD, sfd, &event); if (s == -1) { err_sys("epoll_ctl"); exit(1); } /* Buffer where events are returned */ events = calloc (MAX_EVENTS, sizeof event); //events = (struct epoll_event *)calloc (MAX_EVENTS, sizeof event); /* The event loop */ while (1) { int n, i; n = epoll_wait (efd, events, MAX_EVENTS, -1); for (i = 0; i < n; i++) { if ((events[i].events & EPOLLERR) || (events[i].events & EPOLLHUP) || (!(events[i].events & EPOLLIN))) { /* An error has occured on this fd, or the socket is not ready for reading (why were we notified then?) */ fprintf (stderr, "epoll error\n"); close (events[i].data.fd); continue; } else { /* We have data on the fd waiting to be read. Read and display it. We must read whatever data is available completely, as we are running in edge-triggered mode and won't get a notification again for the same data. */ while (1) { ssize_t count; char buf[2]; count = read (events[i].data.fd, buf, sizeof buf); if (count == -1) { /* If errno == EAGAIN, that means we have read all data. So go back to the main loop. */ if (errno != EAGAIN) { err_sys("read"); } break; } /* Write the buffer to standard output */ s = write (1, buf, count); if (s == -1) { perror ("write"); abort (); } } } } } pause(); return 0; }
// 可能作为服务器接收Cell请求 void * cellinfo_thread(void* p) { CRoute_manager* pCRoute = (CRoute_manager*)p; struct epoll_event event; struct epoll_event* events; int efd; efd = epoll_create(20); event.data.fd = pCRoute->info_fd; event.events = EPOLLIN | EPOLLET; //设置成边沿触发 if(epoll_ctl(efd,EPOLL_CTL_ADD,pCRoute->info_fd,&event) == -1) exit(-1); events = (epoll_event*)calloc(EVENTSNUM, sizeof(epoll_event)); while(1) { int n = epoll_wait(efd,events,EVENTSNUM,-1); for(int i = 0; i < n; i++) { if((events[i].events & EPOLLERR) || (events[i].events & EPOLLHUP) || (!(events[i].events & EPOLLIN))) { perror("epoll error!"); close(events[i].data.fd); continue; } else if(events[i].data.fd == pCRoute->info_fd) { while(1) { struct sockaddr in_addr; socklen_t in_len; int infd; in_len = sizeof(in_addr); infd = accept (pCRoute->info_fd, &in_addr, &in_len); if (infd == -1) { if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) { /* We have processed all incoming connections. */ break; } else { perror ("accept"); break; } } if(make_socket_non_blocking (infd) == -1) exit(-1); event.data.fd = infd; event.events = EPOLLIN | EPOLLET; if(epoll_ctl(efd,EPOLL_CTL_ADD,infd,&event) == -1) exit(-1); } continue; } else if(events[i].events & EPOLLIN) { int n = 0; int nread; int fd = events[i].data.fd; while ((nread = read(fd, pCRoute->infobuf + n, BUFLEN)) > 0) { n += nread; } if (nread == -1 && errno != EAGAIN) { perror("read error"); continue; } if (nread == 0) { event.data.fd = fd; event.events = EPOLLIN | EPOLLET; epoll_ctl(efd,EPOLL_CTL_DEL,fd,&event); close(fd); continue; } event.data.fd = fd; event.events = EPOLLOUT | EPOLLET; epoll_ctl(efd,EPOLL_CTL_MOD,fd,&event); } else if(events[i].events & EPOLLOUT) { int nwrite, data_size = strlen(pCRoute->infobuf); int n = data_size; int fd = events[i].data.fd; while (n > 0) { nwrite = write(fd, pCRoute->infobuf + data_size - n, n); if (nwrite < n) { if (nwrite == -1 && errno != EAGAIN) { perror("write error"); break; } } if(nwrite == 0) // the other side closed { event.data.fd = fd; event.events = EPOLLOUT | EPOLLET; epoll_ctl(efd,EPOLL_CTL_DEL,fd,&event); close(fd); break; } n -= nwrite; } // 重新监听EPOLLIN事件 if(n == 0) // { event.data.fd = fd; event.events = EPOLLIN | EPOLLET; epoll_ctl(efd,EPOLL_CTL_MOD,fd,&event); } } } } }
int main(int argc, char **argv) { struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_handler = SIG_IGN; sa.sa_flags = 0; if(sigaction(SIGPIPE, &sa, NULL)) { LOG_ERR("SIGPIPE ERR"); return 0; } int listenfd; listenfd = open_listenfd(8888); make_socket_non_blocking(listenfd); int epfd = tiny_epoll_create(0); struct epoll_event event; event.data.fd = listenfd; event.events = EPOLLIN | EPOLLET; tiny_epoll_add(epfd, listenfd, &event); tiny_threadpool_t *tp = threadpool_init(2); while(1) { int n = tiny_epoll_wait(epfd, events, MAXEVENTS, -1); int i = 0; for(;i < n;++i){ if (listenfd == events[i].data.fd) { while(1) { struct sockaddr_in clientaddr; socklen_t inlen = sizeof(clientaddr); int infd = accept(listenfd, (struct sockaddr*)&clientaddr,&inlen); if (infd == -1) { if((errno == EAGAIN) || (errno == EWOULDBLOCK)) break; else{ LOG_ERR("accept err"); break; } } LOG_INFO("new client fd : %d",infd); make_socket_non_blocking(infd); event.data.fd = infd; event.events = EPOLLIN | EPOLLET; tiny_epoll_add(epfd, infd, &event); } } else { if((events[i].events & EPOLLERR) || (events[i].events & EPOLLHUP) || !(events[i].events & EPOLLIN)) { LOG_ERR("epoll error fd : %d",events[i].data.fd); close(events[i].data.fd); continue; } LOG_INFO("new task from fd : %d", events[i].data.fd); threadpool_add(tp,accept_request,&(events[i].data.fd)); } } } LOG_INFO("begin destroy"); if(threadpool_destroy(tp,1) < 0) LOG_ERR("idestroy err"); return 0; }
void EpollServer::serve() { #ifdef THREADED_SERVE init_thread(); #endif int sfd, s; int efd; struct epoll_event event; struct epoll_event *events; sfd = makeSvrSocket(); if (sfd == -1) abort(); s = make_socket_non_blocking(sfd); if (s == -1) abort(); reuseSock(sfd); efd = epoll_create(1); if (efd == -1) { perror("epoll_create"); abort(); } event.data.ptr = new EpollData(sfd, NULL); event.events = EPOLLIN | EPOLLET; s = epoll_ctl(efd, EPOLL_CTL_ADD, sfd, &event); if (s == -1) { perror("epoll_ctl"); abort(); } /* Buffer where events are returned */ events = (epoll_event *) calloc(MAX_EVENTS, sizeof event); /* The event loop */ while (1) { int n, i; n = epoll_wait(efd, events, MAX_EVENTS, -1); for (i = 0; i < n; i++) { EpollData *edata = (EpollData*) events[i].data.ptr; if ((events[i].events & EPOLLERR) || (events[i].events & EPOLLHUP) || (!(events[i].events & EPOLLIN))) { /* An error has occured on this fd, or the socket is not ready for reading (why were we notified then?) */ fprintf(stderr, "epoll error\n"); close(edata->fd()); delete edata; continue; } else if (sfd == edata->fd()) { if (_tcp == true) { /* We have a notification on the listening socket, which means one or more incoming connections. */ while (1) { sockaddr *in_addr = (sockaddr *) calloc(1, sizeof(struct sockaddr)); socklen_t in_len = sizeof(struct sockaddr); int infd = accept(sfd, in_addr, &in_len); if (infd == -1) { free(in_addr); if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) { /* We have processed all incoming connections. */ break; } else { perror("accept"); break; } } /* fprintf(stdout, "sin_family[%hu], sin_zero[%s], sin_addr.s_addr[%u], sin_port[%hu]\n", in_addr.sin_family, in_addr.sin_zero, in_addr.sin_addr.s_addr, in_addr.sin_port); */ /* char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV]; getnameinfo(in_addr, in_len, hbuf, sizeof hbuf, sbuf, sizeof sbuf, 0); if (s == 0) { printf("Accepted connection on descriptor %d " "(host=%s, _port=%s)\n", infd, hbuf, sbuf); }*/ /* Make the incoming socket non-blocking and add it to the list of fds to monitor. */ s = make_socket_non_blocking(infd); if (s == -1) { free(in_addr); abort(); } reuseSock(infd); event.data.ptr = new EpollData(infd, in_addr); event.events = EPOLLIN | EPOLLET; s = epoll_ctl(efd, EPOLL_CTL_ADD, infd, &event); if (s == -1) { free(in_addr); perror("epoll_ctl"); abort(); } } continue; } else { int done = 0; while (1) { char buf[Env::BUF_SIZE]; memset(buf, 0, sizeof(buf)); //char *buf = (char*) calloc(Env::BUF_SIZE, sizeof(char)); sockaddr fromaddr; socklen_t sender_len = sizeof(struct sockaddr); ssize_t count = recvfrom(edata->fd(), buf, sizeof buf, 0, &fromaddr, &sender_len); //cout << "EpollServer.cpp: serve(): received "<< count << " bytes."<<endl; if (count == -1) { if (errno != EAGAIN) { perror("read"); done = 1; } } else if (count == 0) { done = 1; break; } else { #ifdef BIG_MSG bool ready = false; string bd = pbrb->getBdStr(sfd, buf, count, ready); if (ready) { #ifdef THREADED_SERVE EventData eventData(edata->fd(), bd.c_str(), bd.size(), fromaddr); _eventQueue.push(eventData); #else _ZProcessor->process(edata->fd(), bd.c_str(), fromaddr); #endif } #endif #ifdef SML_MSG #ifdef THREADED_SERVE EventData eventData(edata->fd(), buf, sizeof(buf), fromaddr); _eventQueue.push(eventData); #else string bufstr(buf); _ZProcessor->process(edata->fd(), bufstr.c_str(), fromaddr); #endif #endif } //memset(buf, 0, sizeof(buf)); //free(buf); } /*if (done) { close(edata->fd()); delete edata; }*/ } } else { if (_tcp == true) { /* We have data on the fd waiting to be read. Read and display it. We must read whatever data is available completely, as we are running in edge-triggered mode and won't get a notification again for the same data. */ int done = 0; while (1) { char buf[Env::BUF_SIZE]; memset(buf, 0, sizeof(buf)); //char *buf = (char*) calloc(Env::BUF_SIZE, sizeof(char)); ssize_t count = recv(edata->fd(), buf, sizeof(buf), 0); if (count == -1) { /* If errno == EAGAIN, that means we have read all data. So go back to the main loop. */ if (errno != EAGAIN) { perror("read"); done = 1; } /*else { printf( "Closed connection on descriptor %d, -1<--recv\n", edata->fd()); close(edata->fd()); delete edata; }*/ break; } else if (count == 0) { /* End of file. The remote has closed the connection. */ done = 1; break; } else { #ifdef BIG_MSG bool ready = false; string bd = pbrb->getBdStr(sfd, buf, count, ready); if (ready) { #ifdef THREADED_SERVE EventData eventData(edata->fd(), bd.c_str(), bd.size(), *edata->sender()); _eventQueue.push(eventData); #else _ZProcessor->process(edata->fd(), bd.c_str(), *edata->sender()); #endif } #endif #ifdef SML_MSG #ifdef THREADED_SERVE EventData eventData(edata->fd(), buf, sizeof(buf), *edata->sender()); _eventQueue.push(eventData); #else string bufstr(buf); _ZProcessor->process(edata->fd(), bufstr.c_str(), *edata->sender()); #endif #endif } //memset(buf, 0, sizeof(buf)); //free(buf); } if (done) { /*printf("Closed connection on descriptor %d, done.\n", edata->fd());*/ /* Closing the descriptor will make epoll remove it from the set of descriptors which are monitored. */ close(edata->fd()); delete edata; } } //if TCP == true } } } free(events); close(sfd); EpollData *edata = (EpollData*) event.data.ptr; delete edata; }
int main (int argc, char *argv[]) { int sfd, s; int efd; struct epoll_event event; struct epoll_event *events; if (argc != 2) { fprintf (stderr, "Usage: %s [port]\n", argv[0]); exit (EXIT_FAILURE); } sfd = create_and_bind (argv[1]); if (sfd == -1) abort (); s = make_socket_non_blocking (sfd); if (s == -1) abort (); s = listen (sfd, SOMAXCONN); if (s == -1) { perror ("listen"); abort (); } efd = epoll_create1 (0); if (efd == -1) { perror ("epoll_create"); abort (); } event.data.fd = sfd; event.events = EPOLLIN | EPOLLET; // READ AND ET s = epoll_ctl (efd, EPOLL_CTL_ADD, sfd, &event); if (s == -1) { perror ("epoll_ctl"); abort (); } /* Buffer where events are returned */ /* function allocates memory for an array of nmemb elements of size bytes each and returns a pointer to the allocated memory. */ /* max event is 64 */ events = calloc (MAXEVENTS, sizeof event); /* The event loop */ while (1) { printf("wait here\n"); int n, i; // RETURN THE ERADY NUMBS // ET AND LT only for the epoll_wait n = epoll_wait (efd, events, MAXEVENTS, -1); for (i = 0; i < n; i++) { if ((events[i].events & EPOLLERR) || (events[i].events & EPOLLHUP) || (!(events[i].events & EPOLLIN))) { /* An error has occured on this fd, or the socket is not ready for reading (why were we notified then?) */ fprintf (stderr, "epoll error\n"); close (events[i].data.fd); continue; } else if (sfd == events[i].data.fd) { /* We have a notification on the listening socket, which means one or more incoming connections. */ while (1) { struct sockaddr in_addr; socklen_t in_len; int infd; char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV]; in_len = sizeof in_addr; // if there is connection wait to process it will return the // infd infd = accept (sfd, &in_addr, &in_len); if (infd == -1) { if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) { /* We have processed all incoming connections. */ break; } else { perror ("accept"); break; } } //it converts a socket address to a corresponding host and service //return numeric host and service s = getnameinfo (&in_addr, in_len, hbuf, sizeof hbuf, sbuf, sizeof sbuf, NI_NUMERICHOST | NI_NUMERICSERV); if (s == 0) { printf ("Accepted connection on descriptor %d " "(host=%s, port=%s)\n", infd, hbuf, sbuf); } /* Make the incoming socket non-blocking and add it to the list of fds to monitor. */ s = make_socket_non_blocking (infd); if (s == -1) abort (); event.data.fd = infd; event.events = EPOLLIN | EPOLLET; s = epoll_ctl (efd, EPOLL_CTL_ADD, infd, &event); if (s == -1) { perror ("epoll_ctl"); abort (); } } continue; } else { /* We have data on the fd waiting to be read. Read and display it. We must read whatever data is available completely, as we are running in edge-triggered mode and won't get a notification again for the same data. */ int done = 0; while (1) { ssize_t count; char buf[512]; count = read (events[i].data.fd, buf, sizeof buf); if (count == -1) { /* If errno == EAGAIN, that means we have read all data. So go back to the main loop. */ if (errno != EAGAIN) { perror ("read"); done = 1; } break; } else if (count == 0) { /* End of file. The remote has closed the connection. */ done = 1; break; } /* Write the buffer to standard output */ s = write (1, buf, count); if (s == -1) { perror ("write"); abort (); } } if (done) { printf ("Closed connection on descriptor %d\n", events[i].data.fd); /* Closing the descriptor will make epoll remove it from the set of descriptors which are monitored. */ close (events[i].data.fd); } } } } free (events); close (sfd); return EXIT_SUCCESS; }
int main(int argc, char **argv) { int listenfd, connfd, port, clientlen; struct sockaddr_in clientaddr; int efd, s; struct epoll_event event; struct epoll_event *events; /* Check command line args */ if (argc != 2) { fprintf(stderr, "usage: %s <port>\n", argv[0]); exit(1); } port = atoi(argv[1]); Signal(SIGCHLD, sigchld_handler); listenfd = Open_listenfd(port); s = make_socket_non_blocking(listenfd); if (s == -1) exit(1); efd = epoll_create1(0); if (efd == -1) { perror("epoll_create"); exit(1); } event.data.fd = listenfd; event.events = EPOLLIN | EPOLLET; s = epoll_ctl(efd, EPOLL_CTL_ADD, listenfd, &event); if (s == -1) { perror("epoll_ctl"); exit(1); } /* Buffer where events are returned */ events = calloc(MAXEVENTS, sizeof event); while (1) { int n, i; n = epoll_wait(efd, events, MAXEVENTS, -1); for (i = 0; i < n; i++) { if ((events[i].events & EPOLLERR) || (events[i].events & EPOLLHUP) || (!(events[i].events & EPOLLIN))) { /* An error has occured on this fd, or the socket is not ready for reading (why were we notified then?) */ fprintf(stderr, "epoll error\n"); close(events[i].data.fd); continue; } else if(listenfd == events[i].data.fd) { /* We have a notification on the listening socket, which means one or more incoming connections. */ while (1) { int infd; clientlen = sizeof(clientaddr); infd = accept(listenfd, (SA *)&clientaddr, (socklen_t*)&clientlen); if (infd == -1) { if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) { /* We have processed all incoming connections. */ break; } else { perror("accept"); break; } } /* Make the incoming socket non-blocking and add it to the list of fds to monitor. */ s = make_socket_non_blocking(infd); if (s == -1) abort(); event.data.fd = infd; event.events = EPOLLIN | EPOLLET; s = epoll_ctl(efd, EPOLL_CTL_ADD, infd, &event); if (s == -1) { perror("epoll_ctl"); abort(); } } continue; } else { /* We have data on the fd waiting to be read. Read and display it. We must read whatever data is available completely, as we are running in edge-triggered mode and won't get a notification again for the same data. */ doit(events[i].data.fd); /* Child serves client */ Close(events[i].data.fd); /* Child closes connection with client */ } } } free(events); Close(connfd); /* Parent closes connected socket (signicant!) */ }
int main(int argc, char *argv[]) { int sfd, s; int efd; struct epoll_event event; struct epoll_event *events; if(argc != 2) { fprintf(stderr, "Usage: %s [port]\n", argv[0]); exit(EXIT_FAILURE); } sfd = create_and_bind(argv[1]); if(sfd == -1) abort(); s = make_socket_non_blocking(sfd); if(s == -1) abort(); s = listen(sfd, SOMAXCONN); if(s == -1) { perror("listen"); abort(); } efd = epoll_create1(0); if(efd == -1) { perror("epoll_create1"); abort(); } event.data.fd = sfd; event.events = EPOLLIN | EPOLLET; s = epoll_ctl(efd, EPOLL_CTL_ADD, sfd, &event); if(s == -1) { perror("epoll_ctl"); abort(); } events = calloc(MAXEVENTS, sizeof(event)); /* The event loop */ while(1) { int n, i; n = epoll_wait(efd, events, MAXEVENTS, -1); for(i = 0; i < n; i++) { if((events[i].events & EPOLLERR) || (events[i].events & EPOLLHUP) || (!(events[i].events & EPOLLIN))) { /*An error occurred, notified but no ready*/ fprintf(stderr, "epoll error\n"); close(events[i].data.fd); continue; } else if(sfd == events[i].data.fd) { /*listener port is notified, which means incoming connection*/ while(1) { struct sockaddr in_addr; socklen_t in_len; int infd; char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV]; in_len = sizeof(in_addr); infd = accept(sfd, &in_addr, &in_len); if(infd == -1) { if((errno == EAGAIN) || (errno == EWOULDBLOCK)) { /*we have processed all incoming connections*/ break; } else { perror("accept"); break; } } s = getnameinfo(&in_addr, in_len, hbuf, sizeof(hbuf), sbuf, sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV); if(s == 0) { printf("Accepted connection on descriptor %d (host=%s, port=%s)\n", infd, hbuf, sbuf); } /*make the socket non-blocking and add it to monitor list*/ s = make_socket_non_blocking(infd); if(s == -1) abort(); event.data.fd = infd; event.events = EPOLLIN | EPOLLET; s = epoll_ctl(efd, EPOLL_CTL_ADD, infd, &event); if(s == -1) { perror("epoll_ctl"); abort(); } } continue; } else { /*read is ready*/ int done = 0; while(1) { ssize_t count; char buf[512]; count = read(events[i].data.fd, buf, sizeof(buf)); if(count == -1) { if(errno != EAGAIN) { perror("read"); done = 1; } break; } else if(count == 0) { /*End of file*/ done = 1; break; } /*Write the buffer to stdout*/ s = write(1, buf, count); if(s == -1) { perror("write"); abort(); } } if(done) { printf("closed connection on descriptor %d\n", events[i].data.fd); /*close connection*/ close(events[i].data.fd); } } } } free(events); close(sfd); return EXIT_SUCCESS; }