int reply_to_client(ae_event_loop *ev_loop, int fd, void *data, int mask) { echoclient *c = (echoclient*)data; strncpy(c->send_buf, c->recv_buf, c->packet_len + 1); int ret, need_write; need_write = c->packet_len + 1 - c->send_buf_len; ret = writen(c, need_write); if (ret == -1) { printf("%s:%d-%d reply to client error\n", c->ip, c->port, c->fd); free_echoclient(c); return -1; }else if (ret == need_write) { c->send_buf[c->packet_len+1] = '\0'; printf("%s:%d-%d reply client send %s\n", c->ip, c->port, c->fd, c->send_buf); if (ae_create_file_event(ev_loop, fd, AE_READABLE, read_from_client, (void*)c) == -1) { printf("%s:%d-%d add reply_to_client event failed\n", c->ip, c->port, c->fd); free_echoclient(c); return -1; } ae_delete_file_event(ev_loop, fd, AE_WRITABLE); reset_echoclient(c); } return 0; }
static void reset_client(client *c) { ae_delete_file_event(conf.el, c->fd, AE_WRITABLE); ae_delete_file_event(conf.el, c->fd, AE_READABLE); ae_create_file_event(conf.el, c->fd, AE_WRITABLE, write_handler, c); c->written = 0; c->read = 0; }
static void write_handler(ae_event_loop *el, int fd, void *priv, int mask) { client *c = (client *)priv; /* Initialize request when nothing was written. */ if (c->written == 0) { if (conf.requests_issued++ >= conf.requests) { free_client(c); return; } c->start = ustime(); c->latency = -1; } if (sdslen(c->obuf) > c->written) { char *ptr = c->obuf + c->written; int nwritten = write(c->fd, ptr, sdslen(c->obuf) - c->written); if (nwritten == -1) { if (errno != EPIPE) { fprintf(stderr, "write failed:%s\n", strerror(errno)); } free_client(c); return; } c->written += nwritten; if (sdslen(c->obuf) == c->written) { ae_delete_file_event(conf.el, c->fd, AE_WRITABLE); ae_create_file_event(conf.el, c->fd, AE_READABLE, read_handler, c); } } }
static client *create_client(const char *content, int len) { client *c = (client *)malloc(sizeof(*c)); c->fd = anet_tcp_nonblock_connect(NULL, conf.hostip, conf.hostport); if (c->fd == ANET_ERR) { fprintf(stderr, "Connect to %s:%d failed\n", conf.hostip, conf.hostport); exit(1); } c->obuf = sdsnewlen(content, len); c->written = 0; c->read = 0; ae_create_file_event(conf.el, c->fd, AE_WRITABLE, write_handler, c); dlist_add_node_tail(conf.clients, c); ++conf.live_clients; return c; }
int main(int argc, char * argv[]) { ae_event_loop * ev_lp = ae_create_event_loop(1024); // ae_create_time_event(ev_lp, 1000, time_loop, NULL, NULL); int retv; retv = mkfifo("tmp.fifo", O_RDWR); int readfd = open("tmp.fifo", O_RDWR | O_NONBLOCK); retv = ae_create_file_event(ev_lp, readfd, AE_READABLE, handle_func, NULL, NULL); if (retv == AE_ERR) { printf("create listen fifo event failed"); return -1; } chmod("tmp.fifo", S_IRWXU | S_IRWXG | S_IRWXO); ae_main(ev_lp); return 0; }
int main(int argc, char **argv) { int listenfd; ae_event_loop *ev_loop; if ((ev_loop = ae_create_event_loop(SETSIZE)) == NULL) { printf("create event loop failed\n"); return -1; } if ((listenfd = create_listen_fd(1000)) == -1) { ae_delete_event_loop(ev_loop); return -1; } if (ae_create_file_event(ev_loop, listenfd, AE_READABLE, accept_tcp_handler, NULL) == AE_ERR) { printf("create listenfd event failed\n"); } ae_main(ev_loop); return 0; }
int read_from_client(ae_event_loop *ev_loop, int fd, void *data, int mask) { echoclient *c = (echoclient*)data; int ret, need_read; if (c->recv_buf_len == 0) { ret = readn(c, 1);//获取内容长度 if (ret == 0) { return 0; } else if (ret == -1) { printf("%s:%d-%d read from client error\n", c->ip, c->port, c->fd); free_echoclient(c); return -1; }else if (ret == -2) { printf("%s:%d-%d client close connection\n", c->ip, c->port, c->fd); free_echoclient(c); return 0; } c->packet_len = c->recv_buf[0]; } need_read = c->packet_len - c->recv_buf_len + 1 ;//1字节长度 ret = readn(c, need_read); if (ret == 0) { return 0; } else if (ret == -1) { printf("%s:%d-%d read from client error\n", c->ip, c->port, c->fd); free_echoclient(c); return -1; } else if (ret == -2) { printf("%s:%d-%d client close connection\n", c->ip, c->port, c->fd); free_echoclient(c); return 0; } else if (ret == need_read) {//read finish c->recv_buf[c->packet_len+1] = '\0'; printf("%s:%d-%d client send %s\n", c->ip, c->port,c->fd, c->recv_buf); if (ae_create_file_event(ev_loop, fd, AE_WRITABLE, reply_to_client, (void*)c) == -1) { printf("%s:%d-%d add reply_to_client event failed\n", c->ip, c->port, c->fd); free_echoclient(c); return -1; } ae_delete_file_event(ev_loop, fd, AE_READABLE); } return 0; }
int accept_tcp_handler(ae_event_loop *ev_loop, int listenfd, void *data, int mask) { int fd; struct sockaddr_in addr; socklen_t len = sizeof(addr); while (1) { fd = accept(listenfd, (struct sockaddr*)&addr, &len); if (fd == -1) { if (errno == EINTR) { continue; } else { perror("accept error\n"); return -1; } } break; } if (set_fd_nonblock(fd) == -1) { return -1; } echoclient *c = (echoclient*)malloc(sizeof(echoclient)); if (ae_create_file_event(ev_loop, fd, AE_READABLE, read_from_client, c) == AE_ERR) { printf("create read_from_client event failed\n"); close(fd); free(c); return -1; } c->fd = fd; c->port = ntohs(addr.sin_port); inet_ntop(AF_INET, (void*)&addr.sin_addr, c->ip, sizeof(c->ip)); c->send_buf[0] = '\0'; c->recv_buf[0] = '\0'; c->send_buf_len = 0; c->packet_len = 0; c->recv_buf_len = 0; c->ev_loop = ev_loop; printf("%s:%d-%d:client connected to server\n", c->ip, c->port, c->fd); return 0; }