int connection_t::on_recv_data() { LOGTRACE((CONNECTION_MODULE, "connection_t::on_recv_data begin")); if (m_enable_hb) { m_service_ptr->async_update_hb_element(m_conn_id); } int recv_ret = 0; int ret = m_read_buffer.recv_to_buffer(m_socket, recv_ret); if (-1 == ret) { //! yunjie: 内存分配失败, 必须回调callback, 否则buffer满了将陷入死循环 LOGWARN((CONNECTION_MODULE, "connection_t::on_recv_data recv_to_buffer failed socket fd:[%u] read buf data size:[%u]", m_socket, m_read_buffer.size() )); on_read_complete(m_read_buffer); return 0; } if (0 == recv_ret) { LOGWARN((CONNECTION_MODULE, "connection_t::on_recv_data recv_ret == 0 socket fd:[%u]", m_socket)); async_close(m_conn_id, true, EV_PASSIVE_CLOSED); return 0; } else if (recv_ret < 0) { //! yunjie: 如果不是EAGAIN或EINTR, 那么就调用callback返回错误信息 if (errno != EAGAIN && errno != EINTR) { if (NULL != m_conn_event_callback) { m_conn_event_callback(EV_ERROR_OCCURRED, m_conn_status, m_conn_id, m_user_data); } } LOGWARN((CONNECTION_MODULE, "connection_t::on_recv_data recv_ret:[%d] socket fd:[%u] errno:[%s]", recv_ret, m_socket, STRERR)); return 0; } else { //! yunjie: 使用者可以实现的虚方法 on_read_complete(m_read_buffer); } LOGTRACE((CONNECTION_MODULE, "connection_t::on_recv_data end")); return 0; }
int connection_t::on_error_occur() { if (NULL != m_conn_event_callback) { //! yunjie: 调用用户注册的回调 m_conn_event_callback(EV_ERROR_OCCURRED, m_conn_status, m_conn_id); } return 0; }
connection_t::~connection_t() { if (NULL != m_conn_event_callback) { m_conn_event_callback(EV_DECONSTRUCT, m_conn_status, m_conn_id, m_user_data); } //! yunjie: 释放I/O缓冲区内存 m_read_buffer.clear(); m_write_buffer.clear(); }
int connection_t::on_error_occur() { LOGTRACE((CONNECTION_MODULE, "connection_t::on_error_occur begin")); if (NULL != m_conn_event_callback) { //! yunjie: 调用用户注册的回调 m_conn_event_callback(EV_ERROR_OCCURRED, m_conn_status, m_conn_id, m_user_data); } LOGTRACE((CONNECTION_MODULE, "connection_t::on_error_occur end")); return 0; }
void connection_t::initialize(fd_t socket_, struct timeval timestamp_, work_service_t* work_service_, conn_type_e conn_type_, on_conn_event_t event_func_, bool enable_hb_) { //! yunjie: 初始化成员 m_socket = socket_; m_timestamp.tv_sec = timestamp_.tv_sec; m_timestamp.tv_usec = timestamp_.tv_usec; m_service_ptr = work_service_; //! yunjie: conn id m_conn_id.socket = socket_; m_conn_id.timestamp.tv_sec = timestamp_.tv_sec; m_conn_id.timestamp.tv_usec = timestamp_.tv_usec; m_conn_id.service_ptr = work_service_; m_conn_type = conn_type_; m_conn_status = ST_ESTABLISHED; m_conn_event_callback = event_func_; m_enable_hb = enable_hb_; if (NULL != m_conn_event_callback) { conn_event_e conn_ev; if (T_PASSIVE == m_conn_type) { conn_ev = EV_ACCEPTED_COMPLETE; } else if (T_ACTIVE == m_conn_type) { conn_ev = EV_CONNECT_SUCCESS; } else { conn_ev = EV_UNKNOWN; } //! yunjie: 调用用户注册的回调 m_conn_event_callback(conn_ev, m_conn_status, m_conn_id); } if (m_enable_hb) { m_service_ptr->async_add_hb_element(m_conn_id); } //! yunjie: 设置I/O缓冲区的最大字节数 m_send_buffer.set_buffer_max_limit(16384); m_read_buffer.set_buffer_max_limit(16384); }
int connection_t::on_send_data() { LOGTRACE((CONNECTION_MODULE, "connection_t::on_send_data begin")); if (m_enable_hb) { m_service_ptr->async_update_hb_element(m_conn_id); } uint32_t transferred_size = 0; while (m_write_buffer.size()) { uint32_t msg_size = m_write_buffer.size(); int32_t ret = ::send(m_socket, m_write_buffer.data(), msg_size, 0); if (0 == ret) { LOGWARN((CONNECTION_MODULE, "connection_t::on_send_data send ret == 0 socket fd:[%u]", m_socket)); async_close(m_conn_id, true, EV_PASSIVE_CLOSED); return 0; } else if (ret < 0) { if (EINTR == errno) { //! yunjie: 立刻重新send LOGWARN((CONNECTION_MODULE, "connection_t::on_send_data recv EINTR send ret:[%d] socket fd:[%u] errno:[%s]", ret, m_socket, STRERR )); continue; } else if (EAGAIN == errno) { //! yunjie: 重新注册I/O事件 m_service_ptr->register_io_event( m_socket, WRITE_EVENT_FLAG, &connection_t::on_peer_event, (void*)this, false ); } else { //! yunjie: 非EINTR,非EAGAIN, 调用上层错误处理函数 if (NULL != m_conn_event_callback) { m_conn_event_callback(EV_ERROR_OCCURRED, m_conn_status, m_conn_id, m_user_data); } } LOGWARN((CONNECTION_MODULE, "connection_t::on_send_data send ret:[%d] socket fd:[%u] errno:[%s]", ret, m_socket, STRERR )); break; } else { transferred_size += ret; m_write_buffer.drain_size(ret); if (ret != (int32_t)msg_size) { m_service_ptr->register_io_event( m_socket, WRITE_EVENT_FLAG, &connection_t::on_peer_event, (void*)this, false ); break; } } } if (transferred_size) { //! yunjie: 使用者可以实现的虚方法 on_write_complete(transferred_size); } if (!m_write_buffer.size()) { m_sending_flag = false; } LOGTRACE((CONNECTION_MODULE, "connection_t::on_send_data end")); return 0; }
int connection_t::initialize( fd_t socket_, const timeval& timestamp_, work_service_t* work_service_, conn_type_e conn_type_, on_conn_event_t event_func_, const inner_conn_sptr_t& self_sptr_, network_config_t* config_, bool enable_hb_ ) { if (-1 == network_tool_t::make_socket_nonblocking(socket_)) { LOGWARN((CONNECTION_MODULE, "connection_t::initialize make_socket_nonblocking failed")); return -1; } //! yunjie: 初始化成员 m_socket = socket_; m_timestamp.tv_sec = timestamp_.tv_sec; m_timestamp.tv_usec = timestamp_.tv_usec; m_service_ptr = work_service_; //! yunjie: conn id m_conn_id.socket = socket_; m_conn_id.timestamp.tv_sec = timestamp_.tv_sec; m_conn_id.timestamp.tv_usec = timestamp_.tv_usec; m_conn_id.service_ptr = work_service_; m_conn_type = conn_type_; m_conn_status = ST_ESTABLISHED; m_conn_event_callback = event_func_; m_self_sptr = self_sptr_; m_config_holder.set_config(config_); m_enable_hb = enable_hb_; //! yunjie: 设置I/O缓冲区的最大字节数 m_write_buffer.set_buffer_max_limit((*m_config_holder).max_send_buffer_size); m_read_buffer.set_buffer_max_limit((*m_config_holder).max_read_buffer_size); //! yunjie: 初始化套接字选项 if (T_ACTIVE == conn_type_) { //! yunjie: 窗口大小设置 int sndbuf_size = (*m_config_holder).tcp_sndbuf_size; if(-1 == ::setsockopt(m_socket, SOL_SOCKET, SO_SNDBUF, &sndbuf_size, sizeof(sndbuf_size))) { LOGWARN((CONNECTION_MODULE, "connection_t::initialize set socket option size of sndbuf failed.")); TEMP_FAILURE_RETRY(::close(m_socket)); return -1; } int rcvbuf_size = (*m_config_holder).tcp_rcvbuf_size; if(-1 == ::setsockopt(m_socket, SOL_SOCKET, SO_RCVBUF, &rcvbuf_size, sizeof(rcvbuf_size))) { LOGWARN((CONNECTION_MODULE, "connection_t::initialize set socket option size of rcvbuf failed.")); TEMP_FAILURE_RETRY(::close(m_socket)); return -1; } } //! yunjie: 屏蔽nagling算法,防止数据量小的指令被打包发送 if ((*m_config_holder).is_enable_tcp_nodelay) { int nodelay = 1; if(::setsockopt(m_socket, IPPROTO_TCP, TCP_NODELAY, (void*)&nodelay, sizeof(nodelay))) { LOGWARN((CONNECTION_MODULE, "connection_t::initialize set nodelay failed socket:[%u]", m_socket)); return -1; } } //! yunjie: connection初始化完毕, 回调通知上层 if (NULL != m_conn_event_callback) { m_conn_event_callback(EV_INIT_COMPLETE, m_conn_status, m_conn_id, m_user_data); } //! yunjie: 注册到event loop中 work_service_->async_add_connection(m_self_sptr); if (m_enable_hb) { m_service_ptr->async_add_hb_element(m_conn_id); } //! yunjie: connection已加入到event loop中, 回调通知上层 if (NULL != m_conn_event_callback) { conn_event_e conn_ev; if (T_PASSIVE == m_conn_type) { conn_ev = EV_ACCEPTED_COMPLETE; } else if (T_ACTIVE == m_conn_type) { conn_ev = EV_CONNECT_SUCCESS; } else { conn_ev = EV_UNKNOWN; } m_conn_event_callback(conn_ev, m_conn_status, m_conn_id, m_user_data); } return 0; }
int connection_t::on_send_data() { if (m_enable_hb) { m_service_ptr->async_update_hb_element(m_conn_id); } bool all_finish = true; int transferred_size = 0; while (m_send_buffer.size()) { uint32_t msg_size = m_send_buffer.size(); int ret = ::send(m_socket, m_send_buffer.data(), msg_size, 0); if (0 == ret) { LOGWARN((CONNECTION_MODULE, "connection_t::on_send_data send ret == 0 socket fd:[%u]", m_socket)); async_close(m_conn_id, true, EV_PASSIVE_CLOSED); return 0; } else if (ret < 0) { LOGWARN((CONNECTION_MODULE, "connection_t::on_send_data send ret:[%d] socket fd:[%u] errno:[%m]", ret, m_socket, errno)); //! yunjie: 如果不是EAGAIN或EINTR, 那么就调用callback返回错误信息 if (errno != EAGAIN && errno != EINTR) { if (NULL != m_conn_event_callback) { m_conn_event_callback(EV_ERROR_OCCURRED, m_conn_status, m_conn_id); } } else { m_service_ptr->register_io_event( m_socket, WRITE_EVENT_FLAG, &connection_t::on_peer_event, (void*)this, false ); } return 0; } else { transferred_size += ret; m_send_buffer.drain_size(ret); if (ret != (int)msg_size) { m_service_ptr->register_io_event( m_socket, WRITE_EVENT_FLAG, &connection_t::on_peer_event, (void*)this, false ); all_finish = false; break; } } } //! yunjie: 使用者可以实现的虚方法 on_write_complete(transferred_size); if (all_finish) { m_sending_flag = false; } return 0; }