inline void FileClient::on_write(int fd, short ev, void *arg) { auto download = static_cast<FileDownload *>(arg); auto buf = download->buf(); // Write the buffer. A portion of the buffer may have been // written in a previous write, so only write the remaining // bytes. auto len = write(fd, buf->head(), buf->nbytes_rem()); if (len == -1) { if (errno == EINTR || errno == EAGAIN) { // The write was interrupted by a signal or we // were not able to write any data to it, // reschedule and return. event_add(download->ev_write(), nullptr); return; } else { // Some other socket error occurred, exit. LOG_ERR("write error in file client"); LOG_ERR("Unknown socket write error occurred"); exit(EXIT_FAILURE); } } else if (len < buf->nbytes_rem()) { // Not all the data was written, update the offset and //reschedule the write event. buf->decr_nbytes_rem(len); event_add(download->ev_write(), nullptr); return; } // The data was completely written, add a read event. download->RequestSent(); event_add(download->ev_read(), nullptr); }
static void zg_write_cb(EV_P_ ev_io *w, int revents) //send by queue { int rc=-1; EV_ALL *cev = (EV_ALL *)(((char *)w) - offsetof (EV_ALL, zg_writew)); unsigned char *buf_ptr_item; send_queue_item_st *item; item = llqueue_poll(cev->zigbee_client.send_queue); buf_ptr_item = item->sendbuf; int sendlen = item->buflen; rc = ev_write(cev->zigbee_client.my_socket, buf_ptr_item, sendlen); if (rc <0) { log_printf(LOG_ERROR, "zg_write_cb,send msg to zigbee middleware failed\n"); //TODO: ERROR HANDLE } else { //send success log_printf(LOG_NOTICE, "[Send2ZW]: %s, %d\n", buf_ptr_item, sendlen); } free(buf_ptr_item); //must free free(item); //must free int q_count = llqueue_count(cev->zigbee_client.send_queue); log_printf(LOG_NOTICE, "[ZigbeeSendQueueCount]=%d\n", q_count); if(q_count <=0) { log_printf(LOG_NOTICE, "[StopZigbeeSendWatcher]send queue empty!\n"); ev_io_stop(cev->mainloop, &cev->zg_writew); } }
inline void FileClient::DownloadFile(std::shared_ptr<FileRequest> request, int ai_family){ ++num_downloads_; struct addrinfo hints, *res, *p; // first, load up address structs with getaddrinfo(): memset(&hints, 0, sizeof hints); hints.ai_family = ai_family; // use IPv4 or IPv6, whichever hints.ai_socktype = SOCK_STREAM; int rv; if((rv = getaddrinfo(request->address()->c_str(), std::to_string(request->port()).c_str(), &hints, &res)) < 0){ LOG_ERR("Error from getaddrinfo: " + std::string(gai_strerror(rv))); } int one = 1; int fd = 0; // loop through until successful connection for(p = res;p != nullptr; p = p->ai_next) { fd = socket(p->ai_family, p->ai_socktype, p->ai_protocol); // make the socket reusable if((rv = evutil_make_listen_socket_reuseable(fd)) < 0){ LOG_ERR("Make reusable failed with code: " + std::to_string(rv)); continue; } // try to connect if ((rv = connect(fd, res->ai_addr, res->ai_addrlen)) < 0) { LOG_ERR("connect failed with code: " + std::to_string(rv)); continue; } // disable Nagle's algorithm if((rv = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof one)) < 0){ LOG_ERR("Set no delay failed with code: " + std::to_string(rv)); continue; } // set the socket to non blocking mode if((rv = evutil_make_socket_nonblocking(fd)) < 0){ LOG_ERR("make non blocking failed with code: " + std::to_string(rv)); continue; } break; // successfully connected } if(p == nullptr){ LOG_ERR("File client connect failed"); exit(EXIT_FAILURE); } // free the linked list freeaddrinfo(res); LOG_DEBUG("Downloading: " + request->file()->filename() + " from: " + std::to_string(request->port()) + " to: " + *request->output_path()); auto d_ptr = new FileDownload(this, request); d_ptr->set_fd(fd); d_ptr->set_ev_read(event_new(base_, fd, EV_READ|EV_PERSIST, FileClient::on_read, d_ptr)); d_ptr->set_ev_write(event_new(base_, fd, EV_WRITE, FileClient::on_write, d_ptr)); event_add(d_ptr->ev_write(), nullptr); }
static void hp_write_cb(EV_P_ ev_io *w, int revents) { int rc=-1; http_cev *hcv = (http_cev *)(((char *)w) - offsetof (http_cev, hp_writew)); rc = ev_write(hcv->http_client.my_socket, hcv->http_client.sendbuf, hcv->http_client.send_len); ev_io_stop(hcv->cev->mainloop, &hcv->hp_writew); if (rc <0) { //TODO: ERROR HANDLE } else log_printf(LOG_NOTICE, "[SEND2HTTP]: %s\n", hcv->http_client.sendbuf); //开始计时,规定时间内没返回当错误处理 //TODO }