void do_read(evutil_socket_t fd, short events, void *arg) { struct fd_state *state = (struct fd_state *)arg; char buf[1024]; size_t result; while (1) { // assert(state->write_event); result = recv(fd, buf, sizeof(buf), 0); if (result <= 0) break; printf("[%s][%d]buf=[%s]len=[%d]\n", __FILE__, __LINE__, buf, result); } memcpy(state->buffer, "reply", sizeof("reply")); assert(state->write_event); event_add(state->write_event, NULL); state->write_upto = state->buffer_used; if (result == 0) { free_fd_state(state); } else if (result < 0) { if (errno == EAGAIN) // XXXX use evutil macro return; perror("recv"); free_fd_state(state); } }
void do_read(evutil_socket_t fd, short events, void *arg) { struct fd_state *state = arg; char buf[1024]; int i; ssize_t result; while (1) { assert(state->write_event); result = recv(fd, buf, sizeof(buf), 0); if (result <= 0) break; printf("DEBUG: read a msg: %s\n", buf); for (i=0; i < result; ++i) { if (state->buffer_used < sizeof(state->buffer)) state->buffer[state->buffer_used++] = rot13_char(buf[i]); if (buf[i] == '\n') { assert(state->write_event); event_add(state->write_event, NULL); state->write_upto = state->buffer_used; } } } if (result == 0) { free_fd_state(state); } else if (result < 0) { if (errno == EAGAIN) // XXXX use evutil macro return; perror("recv"); free_fd_state(state); } }
void lh_epoll(int timeout) { if (rs_state == rs_stopping) { rs_state = rs_stopped; close(_listener); _listener = 0; //fixme: free states close(_epoll); _epoll = 0; lh_clear_callback(); return; } else if (rs_state == rs_stopped) { return; } int n = epoll_wait(_epoll, _events, MAXEVENTS, timeout); for (int i = 0; i < n; i++){ struct epoll_event *event = _events + i; if (_listener == event->data.fd) { //accept struct sockaddr_storage ss; socklen_t slen = sizeof(ss); int fd = accept(_listener, (struct sockaddr*)&ss, &slen); //static int na = 0; //printf("accept:%d\n", ++na); if (fd < 0) { perror("accept"); } else { int err = fcntl(fd, F_SETFL, O_NONBLOCK); if (err){ perror ("make_non_blocking"); return; } struct fd_state *state = alloc_fd_state(fd); struct epoll_event evt; evt.data.ptr = state; evt.events = EPOLLIN; err = epoll_ctl (_epoll, EPOLL_CTL_ADD, fd, &evt); if (err) return; } } else { struct fd_state *state = (struct fd_state*)event->data.ptr; enum io_tatus status = s_ok; if ((event->events & EPOLLERR) ||(event->events & EPOLLHUP)) { //error free_fd_state(state); } else if (event->events & EPOLLIN) { //read status = do_read(state); } else if (event->events & EPOLLOUT) { //write status = do_write(state); } if (status == s_error || status == s_disconnect) { free_fd_state(state); } } } }
void do_read(evutil_socket_t fd, short events, void *arg) { struct fd_state *state = arg; char buf[1024]; int i; ev_ssize_t result; printf("do_read(): fd = %d\r\n", fd); while (1) { assert(state->write_event); result = recv(fd, buf, sizeof(buf), 0); printf("recv(): result = %d\r\n", result); if (result <= 0) break; for (i=0; i < result; ++i) { if (state->buffer_used < sizeof(state->buffer)) state->buffer[state->buffer_used++] = rot13_char(buf[i]); if (buf[i] == '\n') { //assert(state->write_event); //event_add(state->write_event, NULL); state->write_upto = state->buffer_used; buf[state->buffer_used] = '\0'; printf("\r\n"); printf("bufsize = %d, buf = %s\r\n", state->buffer_used, buf); } } } if (result == 0) { free_fd_state(state); } else if (result < 0) { //if (errno == EAGAIN) // XXXX use evutil macro // return; int err = evutil_socket_geterror(fd); if (EVUTIL_ERR_RW_RETRIABLE(err)) { // WSAEWOULDBLOCK or WSAEINTR printf("event_del(state->read_event);\r\n"); event_del(state->read_event); return; } else { perror("recv"); free_fd_state(state); } } }
void do_write(evutil_socket_t fd, short events, void *arg) { struct fd_state *state = arg; while (state->n_written < state->write_upto) { ssize_t result = send(fd, state->buffer + state->n_written, state->write_upto - state->n_written, 0); printf("DEBUG: write a msg: %s\n", state->buffer); if (result < 0) { if (errno == EAGAIN) // XXX use evutil macro return; free_fd_state(state); return; } assert(result != 0); state->n_written += result; } if (state->n_written == state->buffer_used) state->n_written = state->write_upto = state->buffer_used = 1; event_del(state->write_event); }
void do_write(evutil_socket_t fd, short events, void *arg) { struct fd_state *state = arg; //while (state->n_written < state->write_upto) { //ssize_t result = send(fd, state->buffer + state->n_written, //state->write_upto - state->n_written, 0); char res[] = {'a','b','\0','d'}; ssize_t result = send(fd, res/*state->buffer*/,sizeof(res) /*strlen(state->buffer)*/, 0); if (result < 0) { if (errno == EAGAIN) // XXX use evutil macro return; free_fd_state(state); return; } assert(result != 0); state->n_written += result; } //if (state->n_written == state->buffer_used) { state->n_written = state->write_upto = state->buffer_used = 1; } event_del(state->write_event); }
void do_write(evutil_socket_t fd, short events, void *arg) { struct fd_state *state = (struct fd_state *)arg; printf("[%d]\n", __LINE__); //while (state->n_written < state->write_upto) { //ssize_t result = send(fd, state->buffer + state->n_written, //state->write_upto - state->n_written, 0); size_t result = send(fd, state->buffer, strlen(state->buffer), 0); if (result < 0) { if (errno == EAGAIN) // XXX use evutil macro return; free_fd_state(state); return; } assert(result != 0); state->n_written += result; } //if (state->n_written == state->buffer_used) { state->n_written = state->write_upto = state->buffer_used = 1; } event_del(state->write_event); }
void do_read(evutil_socket_t fd, short events, void *arg) { printf("begin read !\n"); struct fd_state *state = arg; char buf[1024]; int i = 0; ssize_t result; bzero(buf,sizeof(buf)); while (1) { // assert(state->write_event); result = read(fd, buf + i,1); if (result <= 0) break; i += result; printf("[%s][%d]buf=[%s]len=[%d]\n", __FILE__, __LINE__, buf,result); } char* el = memchr(buf, '\n',i); printf("end : %s\n",el); memcpy(state->buffer,buf,sizeof(buf)); assert(state->write_event); event_add(state->write_event, NULL); state->write_upto = state->buffer_used; printf("result : %d buf total : %s\n",result,state->buffer); if (result == 0) { perror("client closed"); free_fd_state(state); } else if (result < 0) { if (errno == EAGAIN) // XXXX use evutil macro return; perror("recv"); free_fd_state(state); } }
void do_write(evutil_socket_t fd, short events, void *arg) { (void) events; struct fd_state *state = arg; printf("Want to write %d blocks\n", List_count(state->outputs)); while (List_count(state->outputs) > 0) { RtmpOutputMessage *this_output = List_first(state->outputs); printf("Block write: %u\n", this_output->data_left); while (this_output->data_left > 0) { ssize_t result = send(fd, rtmp_output_message_start_at(this_output), this_output->data_left, 0); if (result < 0) { if (errno == EAGAIN) // XXX use evutil macro return; free_fd_state(state); return; } assert(result != 0); this_output->data_left -= result; printf("\tWritten: %d\n", result); if (this_output->data_left == 0) { List_unshift(state->outputs); rtmp_destroy_output_message(this_output); break; } } } event_del(state->write_event); }
void run(void) { int listener; struct fd_state *state[FD_SETSIZE]; struct sockaddr_in sin; int i, maxfd; fd_set readset, writeset, exset; sin.sin_family = AF_INET; sin.sin_addr.s_addr = 0; sin.sin_port = htons(8081); for (i = 0; i < FD_SETSIZE; ++i) state[i] = NULL; listener = socket(AF_INET, SOCK_STREAM, 0); make_nonblocking(listener); if (bind(listener, (struct sockaddr*)&sin, sizeof(sin)) < 0) { perror("bind"); return; } if (listen(listener, 16)<0) { perror("listen"); return; } FD_ZERO(&readset); FD_ZERO(&writeset); FD_ZERO(&exset); while (1) { maxfd = listener; FD_ZERO(&readset); FD_ZERO(&writeset); FD_ZERO(&exset); FD_SET(listener, &readset); for (i=0; i < FD_SETSIZE; ++i) { if (state[i]) { if (i > maxfd) maxfd = i; FD_SET(i, &readset); if (state[i]->writing) { FD_SET(i, &writeset); } } } if (select(maxfd+1, &readset, &writeset, &exset, NULL) < 0) { perror("select"); return; } if (FD_ISSET(listener, &readset)) { struct sockaddr_storage ss; socklen_t slen = sizeof(ss); int fd = accept(listener, (struct sockaddr*)&ss, &slen); if (fd < 0) { perror("accept"); } else if (fd > FD_SETSIZE) { close(fd); } else { make_nonblocking(fd); state[fd] = alloc_fd_state(); char send_buf[1024] = "Connected"; send(fd, send_buf, 1024, 0); assert(state[fd]);/*XXX*/ } } for (i=0; i < maxfd+1; ++i) { int r = 0; if (i == listener) continue; if (FD_ISSET(i, &readset)) { r = do_read(i, state[i]); } if (r == 0 && FD_ISSET(i, &writeset)) { r = do_write(i, state[i]); } if (r) { free_fd_state(state[i]); state[i] = NULL; close(i); } } } }
void run(void) { evutil_socket_t sender; struct sockaddr_in sin; struct event_base *base; struct event *write_event = NULL; struct event *read_event = NULL; struct fd_state *state; int result; base = event_base_new(); if (!base) return; /*XXXerr*/ sin.sin_family = AF_INET; sin.sin_addr.s_addr = 0; sin.sin_addr.s_addr = inet_addr("127.0.0.1"); sin.sin_port = htons(40713); sender = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); evutil_make_socket_nonblocking(sender); #ifndef WIN32 { int one = 1; setsockopt(sender, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); } #endif /* if (bind(sender, (struct sockaddr*)&sin, sizeof(sin)) < 0) { perror("bind"); return; } sender_event = event_new(base, sender, EV_READ|EV_PERSIST, do_read, (void*)base); /-*XXX check it *-/ event_add(sender_event, NULL); //*/ result = connect(sender, (struct sockaddr*)&sin, sizeof(sin)); if (result < 0 || result == SOCKET_ERROR) { if (WSAGetLastError() == WSAEWOULDBLOCK) { printf("WSAGetLastError() = WSAEWOULDBLOCK\r\n"); Sleep(1000); printf("Press any key to continue...\r\n"); //system("pause"); } else { printf("connect error!\r\n"); printf("WSAGetLastError() = 0x%08X\r\n", WSAGetLastError()); system("pause"); perror("connect"); return; } } //printf("Press any key to continue...\r\n"); //system("pause"); //write_event = event_new(base, sender, EV_WRITE|EV_PERSIST, do_write, (void*)base); //read_event = event_new(base, sender, EV_READ |EV_PERSIST, do_read, (void*)base); state = alloc_fd_state(base, sender); /* if (write_event) { printf("event_add(write_event, NULL);\r\n"); event_add(write_event, NULL); } //*/ if (state && state->write_event) { printf("event_add(state->write_event, NULL);\r\n"); event_add(state->write_event, NULL); } if (state && state->read_event) { printf("event_add(state->read_event, NULL);\r\n"); event_add(state->read_event, NULL); } printf("event_base_dispatch(base);\r\n"); event_base_dispatch(base); /* if (write_event) event_free(write_event); if (read_event) event_free(read_event); //*/ if (state) free_fd_state(state); }
void do_read(evutil_socket_t fd, short events, void *arg) { (void) events; struct fd_state *state = arg; ssize_t result; while (1) { assert(state->write_event); result = recv(fd, RingBuffer_ends_at(state->buffer), RingBuffer_available_space(state->buffer), 0); if (result <= 0) break; state->rtmp->total_read += result; RingBuffer_commit_write(state->buffer, result); while (RingBuffer_available_data(state->buffer) > 0) { RtmpOutputMessage *this_output = rtmp_create_output_message(); int result_multiplex = rtmp_multiplex(state->rtmp, state->buffer, this_output); check(result_multiplex >= 0, "rtmp_multiplex error %d", result_multiplex); if (state->rtmp->end == 1) { event_del(state->write_event); rtmp_destroy_output_message(this_output); free_fd_state(state); return; } if (this_output->length > 0) { printf("Add block with length=%u\n", this_output->length); List_push(state->outputs, this_output); assert(state->write_event); event_add(state->write_event, NULL); } else { rtmp_destroy_output_message(this_output); } if (result_multiplex == 0) break; } printf("total_read=%u, last_total_read=%u\n", state->rtmp->total_read, state->rtmp->last_total_read); if (rtmp_should_acknowledge(state->rtmp) == 1) { RtmpOutputMessage *ack = rtmp_create_output_message(); rtmp_allocate_output_message_content(ack, 16); int i = 0; unsigned char *msg = ack->message; msg[i++] = 0x02; msg[i++] = 0x00;msg[i++] = 0x00;msg[i++] = 0x00; int_to_byte_array(4, msg, i, 3);i += 3; msg[i++] = 0x03; msg[i++] = 0x00; msg[i++] = 0x00; msg[i++] = 0x00; msg[i++] = 0x00; // msg[i++] = 0x03; // msg[i++] = 0x00;msg[i++] = 0x00;msg[i++] = 0x04; // msg[i++] = 0x00;msg[i++] = 0x00;msg[i++] = 0x00;msg[i++] = 0x00; // msg[i++] = 0x00;msg[i++] = 0x00;msg[i++] = 0x00; int_to_byte_array(state->rtmp->total_read, msg, i, 4);i += 4; List_push(state->outputs, ack); assert(state->write_event); event_add(state->write_event, NULL); state->rtmp->last_total_read = state->rtmp->total_read; } } if (result == 0) { free_fd_state(state); } else if (result < 0) { if (errno == EAGAIN) // XXXX use evutil macro return; perror("recv"); free_fd_state(state); } error: free_fd_state(state); return; }
void WorkerServer::read_callback(evutil_socket_t socket, short event, void *arg) { std::cout << "read callback" << std::endl; struct fd_state* state = (struct fd_state*)(arg); /* recv json and return ack then download */ char *buffer; char jsonMsgLen[2]; Json::Reader reader; Json::Value value; /* mark is a flag * mark = 1 upload (breakpoint_upload) * mark = 2 download (breakpoint_download) * mark = 3 multithread download (file_block_download) * */ int mark = 0; std::string md5; unsigned long size = 0; unsigned long offset = 0; unsigned long start = 0; unsigned long end = 0; int threadNum = 0; union Len len; /* recv request (json)*/ /* * Json: * { * mark:1, 标识 * md5:asd7qwebuuaweg12i3ehiqwueh, * size:1900, 文件大小 * offset:0, 偏移量 偏移量不为 0 则进行断点上传或下载 * thread:1, 多线程下载 * } * */ /* 先接收 2 字节 json 长度 len,接着接受长度为 len 的 json 串 */ int ret = recv(socket, jsonMsgLen, 2, MSG_WAITALL); if(ret < 0) { if(errno == EAGAIN && errno == EWOULDBLOCK) { std::cout << "recv errno" << std::endl; free_fd_state(state); close(socket); return; } } else if(ret == 0) { free_fd_state(state); return; } else { len.length = 0; len.c[0] = jsonMsgLen[0]; len.c[1] = jsonMsgLen[1]; printf("bufferlength:%d\n", len.length); } if((buffer = (char*)malloc(sizeof(char) * len.length)) == NULL) { perror("malloc error"); return; } /* 即使设置 MSG_WAITALL 标识,不代表能接收 bufferlength 长度的数据包,需自己判定 */ int recvnum; if((recvnum = recv(socket, buffer, len.length, MSG_WAITALL)) == len.length) { printf("buffer:%s\n", buffer); event_del(state->read_event); } else { free_fd_state(state); printf("recv return:%d\n", len.length); return; } /* parse json */ if(reader.parse(buffer, value)) { if(!value["mark"].isNull()) { mark = value["mark"].asInt(); md5 = value["md5"].asString(); threadNum = value["threadNum"].asInt(); if(mark == 3) { start = value["start"].asLargestUInt(); end = value["end"].asLargestUInt(); std::cout << "start:" << start << std::endl; std::cout << "end:" << end << std::endl; } else { size = value["size"].asLargestUInt(); offset = value["offset"].asLargestUInt(); /* check argument is correct*/ if(detect_paramenter_correct(mark, md5, size, offset, threadNum) == false) { perror("detect parament error"); return; } std::cout << "size:" << size << std::endl; std::cout << "offset:" << offset << std::endl; } std::cout << "mark:" << mark << std::endl; std::cout << "md5:" << md5 << std::endl; std::cout << "threadNum:" << threadNum << std::endl; /* create handle event */ Handler handle_event; /* parse mark, handler event */ switch(mark) { case 1: handle_event = std::make_tuple(WorkerServer::handler_upload, socket, md5, size, offset, threadNum); threadpool.AddTask(std::move(handle_event)); break; case 2: handle_event = std::make_tuple(WorkerServer::handler_download, socket, md5, size, offset, threadNum); threadpool.AddTask(std::move(handle_event)); break; case 3: handle_event = std::make_tuple(WorkerServer::file_block_download, socket, md5, start, end, threadNum); threadpool.AddTask(std::move(handle_event)); break; default: break; } } } if(buffer != NULL) { free(buffer); } }