Esempio n. 1
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;
}
Esempio n. 2
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;
}