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; }
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); }
static void connection_read_handle(struct connection_s* self) { struct buffer_s* recv_buffer =self->recv_buffer; bool is_close = false; bool proc_begin = false; int all_recv_len = 0; procbegin: proc_begin = false; all_recv_len = 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(self->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 { ox_buffer_addwritepos(recv_buffer, recv_len); all_recv_len += recv_len; if(recv_len == can_recvlen) { /* 如果全部读取,则设置标志:处理完刚接收的数据后应该继续读取 */ proc_begin = true; } } } break; } if(is_close) { connection_send_logicmsg(self, net_msg_close, NULL, 0); connection_close(self); } else if(all_recv_len > 0) { int len = connection_split_packet(self); ox_buffer_addreadpos(recv_buffer, len); } if(proc_begin && self->fd != SOCKET_ERROR) { goto procbegin; } }
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; } }