bool File::_send_file_protocol_to_chunk(TransSocket* trans_socket, ProtocolFile *protocol_file, ByteBuffer *byte_buffer, int fd) { byte_buffer->clear(); //1 预留头部空间 int header_length; ProtocolHeader *header = protocol_file->get_protocol_header(); header_length = header->get_header_length(); byte_buffer->reserve(header_length); //2 编码协议体 if(!protocol_file->encode_body(byte_buffer)) { SLOG_ERROR("encode body error"); return false; } //3 添加数据 if(fd > 0) { FileSeg& file_seg = protocol_file->get_file_seg(); char *data_buffer = byte_buffer->get_append_buffer(file_seg.size); if(read(fd, data_buffer, file_seg.size) != file_seg.size) { SLOG_ERROR("read file error. errno=%d(%s).", errno, strerror(errno)); return false; } byte_buffer->set_append_size(file_seg.size); } //4. 编码协议头 int body_length = byte_buffer->size()-header_length; char *header_buffer = byte_buffer->get_data(0, header_length); if(!header->encode(header_buffer, body_length)) { SLOG_ERROR("encode header error"); return false; } //5. 发送数据 if(trans_socket->send_data_all(byte_buffer->get_data(), byte_buffer->size()) == TRANS_ERROR) { SLOG_ERROR("send data error"); return false; } return true; }
//要求fd是非阻塞的 HANDLE_RESULT NetInterface::on_readable(int fd) { SLOG_TRACE("socket on_readable. fd=%d", fd); TransSocket* trans_socket = (TransSocket*)m_socket_manager->find_trans_socket(fd); if(trans_socket == NULL) { SLOG_ERROR("can't find trans socket in socket manager. fd=%d", fd); return HANDLE_ERROR; } ByteBuffer *raw_data_buffer = NULL; unsigned int header_length = 0; ProtocolHeader *header = m_protocol_family->create_protocol_header(); assert(header != NULL); header_length = header->get_header_length(); assert(header_length > 0); //1. 检查是否有未处理数据 raw_data_buffer = trans_socket->pop_recv_buffer(); if(raw_data_buffer == NULL) //新的协议包 raw_data_buffer = new ByteBuffer(); unsigned int raw_data_size = raw_data_buffer->size(); if(raw_data_size < header_length) //读协议头数据 { int need_size = header_length-raw_data_size; int recv_size = trans_socket->recv_buffer(raw_data_buffer, need_size, false); if(recv_size == TRANS_ERROR) { SLOG_ERROR("receive protocol header error. fd=%d", fd); delete raw_data_buffer; m_protocol_family->destroy_protocol_header(header); return HANDLE_ERROR; } else if(recv_size < need_size) //还有部分协议头数据未接收 { SLOG_DEBUG("protocol header incomplete[need=%d,recv=%d]. waiting for the remaining data.", need_size, recv_size); trans_socket->push_recv_buffer(raw_data_buffer); m_protocol_family->destroy_protocol_header(header); return HANDLE_OK; } raw_data_size += recv_size; } //2. 解码协议头 int body_length = 0; char *header_buffer = raw_data_buffer->get_data(0, header_length); assert(header_buffer != NULL); if(header->decode(header_buffer, body_length) == false) { SLOG_ERROR("decode protocol header error. fd=%d", fd); delete raw_data_buffer; m_protocol_family->destroy_protocol_header(header); return HANDLE_ERROR; } //3. 接收协议体数据 if(body_length > 0) //允许空协议体 { int need_size = body_length+header_length-raw_data_size; int recv_size = trans_socket->recv_buffer(raw_data_buffer, need_size, false); if(recv_size == TRANS_ERROR) { SLOG_ERROR("receive protocol body error. fd=%d", fd); delete raw_data_buffer; m_protocol_family->destroy_protocol_header(header); return HANDLE_ERROR; } else if(recv_size < need_size) //还有部分协议体数据未接收 { SLOG_DEBUG("protocol body incomplete[need=%d,recv=%d]. waiting for the remaining data.", need_size, recv_size); trans_socket->push_recv_buffer(raw_data_buffer); m_protocol_family->destroy_protocol_header(header); return HANDLE_OK; } } //4. 解码协议体 Protocol *protocol = m_protocol_family->create_protocol_by_header(header); if(protocol == NULL) { SLOG_ERROR("create protocol error. fd=%d", fd); delete raw_data_buffer; m_protocol_family->destroy_protocol_header(header); return HANDLE_ERROR; } protocol->set_protocol_family(m_protocol_family); /*****由protocol托管header到释放******/ protocol->attach_protocol_header(header); char *body_buffer = NULL; if(body_length > 0) body_buffer = raw_data_buffer->get_data(header_length, body_length); if(protocol->decode_body(body_buffer, body_length) == false) { SLOG_ERROR("decode protocol body error. fd=%d", fd); delete raw_data_buffer; m_protocol_family->destroy_protocol(protocol); return HANDLE_ERROR; } /***** 由protocol托管raw_data的释放 ******/ protocol->attach_raw_data(raw_data_buffer); //6. 调用回调函数向应用层发协议 bool detach_protocol = false; int result = on_recv_protocol(fd, protocol, detach_protocol); if(result==-1 || detach_protocol==false) m_protocol_family->destroy_protocol(protocol); return HANDLE_OK; }