예제 #1
0
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;
}
예제 #2
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;
}
예제 #3
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();
}
예제 #4
0
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;
}
예제 #5
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);
}
예제 #6
0
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;
}
예제 #7
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;
}
예제 #8
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;
}