void SSDBProtocolRequest::appendBlock(const char* data, size_t len) { if (ox_buffer_getwritevalidcount(m_request) < len) { buffer_s* temp = ox_buffer_new(ox_buffer_getsize(m_request) + len); memcpy(ox_buffer_getwriteptr(temp), ox_buffer_getreadptr(m_request), ox_buffer_getreadvalidcount(m_request)); ox_buffer_addwritepos(temp, ox_buffer_getreadvalidcount(m_request)); ox_buffer_delete(m_request); m_request = temp; } ox_buffer_write(m_request, data, len); }
bool ox_buffer_write(struct buffer_s* self, const char* data, size_t len) { bool write_ret = true; if(ox_buffer_getwritevalidcount(self) >= len) { /* 直接写入 */ memcpy(ox_buffer_getwriteptr(self), data, len); ox_buffer_addwritepos(self, len); } else { size_t left_len = self->data_len - ox_buffer_getreadvalidcount(self); if(left_len >= len) { ox_buffer_adjustto_head(self); ox_buffer_write(self, data, len); } else { write_ret = false; } } return write_ret; }
static int connection_split_packet(struct connection_s* self) { int proc_len = 0; struct buffer_s* recv_buffer = self->recv_buffer; const char* buffer = ox_buffer_getreadptr(recv_buffer); int left_len = ox_buffer_getreadvalidcount(recv_buffer); while(left_len > 0) { /* 调用验证包完整回调函数:如果收到完整包则投递到逻辑层 */ int packet_len = (self->check)(buffer, left_len, self->ext); if(packet_len > 0) { connection_send_logicmsg(self, net_msg_data, buffer, packet_len); buffer += packet_len; left_len -= packet_len; proc_len += packet_len; } else { break; } } return proc_len; }
void ox_buffer_adjustto_head(struct buffer_s* self) { size_t len = 0; if(self->read_pos > 0) { len = ox_buffer_getreadvalidcount(self); if(len > 0 ) { memmove(self->data, self->data+self->read_pos, len); } self->read_pos = 0; self->write_pos = len; } }
/* 发送内置缓冲区未发送的数据 */ static void epollserver_send_olddata(struct session_s* session) { int send_len = 0; struct buffer_s* send_buffer = session->send_buffer; int oldlen = ox_buffer_getreadvalidcount(send_buffer); if(oldlen > 0) { send_len = ox_socket_send(session->fd, ox_buffer_getreadptr(send_buffer), oldlen); if(send_len > 0) { ox_buffer_addwritepos(send_buffer, send_len); } session->writeable = (oldlen == oldlen); } return; }
static void epoll_handle_onoutevent(struct session_s* session) { struct server_s* server = &session->server->base; session->writeable = true; if(server->logic_on_sendfinish != NULL) { (server->logic_on_sendfinish)(server, session->ud, 0); } else { if(ox_buffer_getreadvalidcount(session->send_buffer) > 0) { epollserver_send_olddata(session); } if(session->writeable && session->haveleftdata) { /* 如果socket仍然可写且逻辑层有未发送的数据则通知逻辑层 */ struct server_s* server = &session->server->base; (server->logic_on_cansend)(server, session->ud); } } }
int SSDBProtocolRequest::getResultLen() { return ox_buffer_getreadvalidcount(m_request); }
static void connection_sendmsg_handle(struct connection_s* self) { if(self->status == connection_establish) { struct buffer_s* send_buffer = self->send_buffer; int send_len = 0; proc_send: { struct rwlist_s* free_sendmsg_list = self->free_sendmsg_list; struct rwlist_s* sendmsg_list = self->sendmsg_list; struct msg_data_s** msg = NULL; while((msg = (struct msg_data_s**)ox_rwlist_front(sendmsg_list, 0)) != NULL) { struct msg_data_s* data = *msg; /* 只处理发送数据的消息 */ if(data->type == send_msg_data) { /* 先写入内置缓冲区 */ if(ox_buffer_write(send_buffer, data->data, data->len)) { assert(data->msg_id == self->last_send_msg_id+1); self->last_send_msg_id++; ox_rwlist_pop(sendmsg_list, 0); ox_rwlist_push(free_sendmsg_list, msg); } else { break; } } else { ox_rwlist_pop(sendmsg_list, 0); ox_rwlist_push(free_sendmsg_list, msg); } } } send_len = ox_buffer_getreadvalidcount(send_buffer); if(send_len > 0) { /* 发送内置缓冲区 */ int ret_len = send(self->fd, ox_buffer_getreadptr(send_buffer), send_len, 0); if(ret_len > 0) { ox_buffer_addreadpos(send_buffer, ret_len); if(send_len == ret_len) { /* 如果发送全部成功,则继续处理发送消息队列中的消息 */ goto proc_send; } } else if(ret_len == SOCKET_ERROR) { if(S_EWOULDBLOCK == sErrno) { self->writable = false; ox_fdset_add(self->fdset, self->fd, WriteCheck); } } } } }
static void epoll_recvdata_callback(void* msg) { struct session_s* session = (struct session_s*)msg; struct buffer_s* recv_buffer = session->recv_buffer; struct server_s* server = &(session->server->base); int all_recvlen = 0; bool is_close = false; bool proc_begin = false; if(session->fd == SOCKET_ERROR) { return; } procbegin: proc_begin = false; all_recvlen = 0; for(;;) { int can_recvlen = 0; int recv_len = 0; if(ox_buffer_getwritevalidcount(recv_buffer) <= 0) { ox_buffer_adjustto_head(recv_buffer); } can_recvlen = ox_buffer_getwritevalidcount(recv_buffer); if(can_recvlen > 0) { recv_len = recv(session->fd, ox_buffer_getwriteptr(recv_buffer), can_recvlen, 0); if(recv_len == 0) { is_close = true; } else if(SOCKET_ERROR == recv_len) { is_close = (S_EWOULDBLOCK != sErrno); } else { all_recvlen += recv_len; ox_buffer_addwritepos(recv_buffer, recv_len); if(recv_len == can_recvlen) { proc_begin = true; } } } break; } if(is_close) { epollserver_halfclose_session(session->server, session); (*server->logic_on_close)(server, session->ud); } else if(all_recvlen > 0) { int proc_len = (*server->logic_on_recved)(server, session->ud, ox_buffer_getreadptr(recv_buffer), ox_buffer_getreadvalidcount(recv_buffer)); ox_buffer_addreadpos(recv_buffer, proc_len); } if(proc_begin && session->fd != SOCKET_ERROR) /* 确保逻辑层在logic_on_recved中没有调用关闭session */ { goto procbegin; } }