zan-extension/src/workers/zanNetWorker.c
/**
 * send to client or append to out_buffer
 */
send to client or append to out_buffer
send to client or append to out_buffer
int zanNetworker_send(swSendData *_send)
{
    zanServer *serv = ServerG.serv;
    uint32_t session_id   = _send->info.fd;
    uint32_t _send_length = _send->length;
    void      *_send_data = _send->data;
    swConnection *conn = zanServer_verify_connection(serv, session_id);
    if (!conn)
    {
        zanTrace("send event:%d byte:%d  failed, session#%d does not exist.", _send->info.type, _send_length, session_id);
        return ZAN_ERR;
    }
    int fd = conn->fd;
    swReactor *reactor = ServerG.main_reactor;
    if (_send->info.type == SW_EVENT_CLOSE && conn->close_reset)
    {
        reactor->close(reactor, fd);
        return ZAN_OK;
    }
    int buffer_type = 0;
    if (swBuffer_empty(conn->out_buffer))
    {
        if (_send->info.type == SW_EVENT_CLOSE)
        {
            reactor->close(reactor, fd);
            return ZAN_OK;
        }
#ifdef SW_REACTOR_SYNC_SEND
        if (_send->info.type != SW_EVENT_SENDFILE)
        {
            if (!conn->direct_send)
            {
                buffer_type = 1;
            }
            else
            {
                int n = 0;
                while(!n)
                {
                    n = swConnection_send(conn, _send_data, _send_length, 0);
                    if (n == _send_length)
                    {
                        return ZAN_OK;
                    }
                    else if(n > 0)
                    {
                        _send_data += n;
                        _send_length -= n;
                        buffer_type = 1;
                        break;
                    }
                    else if(errno == EINTR)
                    {
                        n = 0;
                    }
                    else
                    {
                        buffer_type = 1;
                        break;
                    }
                }
            }
        }
#endif
        else
        {
            if (!conn->out_buffer)
            {
                conn->out_buffer = swBuffer_new(SW_BUFFER_SIZE);
                if (conn->out_buffer == NULL)
                {
                    return ZAN_ERR;
                }
            }
        }
    }
    if(buffer_type == 1)
    {
        if (!conn->out_buffer)
        {
            conn->out_buffer = swBuffer_new(SW_BUFFER_SIZE);
            if (conn->out_buffer == NULL)
            {
                return ZAN_ERR;
            }
        }
        buffer_type = 0;
    }
    swBuffer_trunk *trunk;
    if (_send->info.type == SW_EVENT_CLOSE)
    {
        trunk = swBuffer_new_trunk(conn->out_buffer, SW_CHUNK_CLOSE, 0);
        trunk->store.data.val1 = _send->info.type;
    }
    else if (_send->info.type == SW_EVENT_SENDFILE)
    {
        swConnection_sendfile_async(conn, _send_data);
    }
    else
    {
        if (conn->removed)
        {
            zanTrace("connection#%d is closed by client.", fd);
            return ZAN_ERR;
        }
        if (conn->out_buffer->length >= ServerG.servSet.buffer_output_size)
        {
            zanTrace("connection#%d output buffer overflow.", fd);
            conn->overflow = 1;
        }
        int _length = _send_length;
        void* _pos = _send_data;
        int _n;
        while (_length > 0)
        {
            _n = _length >= SW_BUFFER_SIZE_BIG ? SW_BUFFER_SIZE_BIG : _length;
            swBuffer_append(conn->out_buffer, _pos, _n);
            _pos += _n;
            _length -= _n;
        }
    }
    if (reactor->set(reactor, fd, SW_EVENT_TCP | SW_EVENT_WRITE | SW_EVENT_READ) < 0
            && (errno == EBADF || errno == ENOENT))
    {
        reactor->close(reactor, fd);
        return ZAN_OK;
    }
    return ZAN_OK;
}
int zanNetworker_send ( swSendData * _send ) { zanServer * serv = ServerG . serv ; uint32_t session_id = _send -> info . fd ; uint32_t _send_length = _send -> length ; void * _send_data = _send -> data ; swConnection * conn = zanServer_verify_connection ( serv , session_id ) ; if ( ! conn ) { zanTrace ( " " , _send -> info . type , _send_length , session_id ) ; return ZAN_ERR ; } int fd = conn -> fd ; swReactor * reactor = ServerG . main_reactor ; if ( _send -> info . type == SW_EVENT_CLOSE && conn -> close_reset ) { reactor -> close ( reactor , fd ) ; return ZAN_OK ; } int buffer_type = 0 ; if ( swBuffer_empty ( conn -> out_buffer ) ) { if ( _send -> info . type == SW_EVENT_CLOSE ) { reactor -> close ( reactor , fd ) ; return ZAN_OK ; } #ifdef SW_REACTOR_SYNC_SEND if ( _send -> info . type != SW_EVENT_SENDFILE ) { if ( ! conn -> direct_send ) { buffer_type = 1 ; } else { int n = 0 ; while ( ! n ) { n = swConnection_send ( conn , _send_data , _send_length , 0 ) ; if ( n == _send_length ) { return ZAN_OK ; } else if ( n > 0 ) { _send_data += n ; _send_length -= n ; buffer_type = 1 ; break ; } else if ( errno == EINTR ) { n = 0 ; } else { buffer_type = 1 ; break ; } } } } #endif else { if ( ! conn -> out_buffer ) { conn -> out_buffer = swBuffer_new ( SW_BUFFER_SIZE ) ; if ( conn -> out_buffer == NULL ) { return ZAN_ERR ; } } } } if ( buffer_type == 1 ) { if ( ! conn -> out_buffer ) { conn -> out_buffer = swBuffer_new ( SW_BUFFER_SIZE ) ; if ( conn -> out_buffer == NULL ) { return ZAN_ERR ; } } buffer_type = 0 ; } swBuffer_trunk * trunk ; if ( _send -> info . type == SW_EVENT_CLOSE ) { trunk = swBuffer_new_trunk ( conn -> out_buffer , SW_CHUNK_CLOSE , 0 ) ; trunk -> store . data . val1 = _send -> info . type ; } else if ( _send -> info . type == SW_EVENT_SENDFILE ) { swConnection_sendfile_async ( conn , _send_data ) ; } else { if ( conn -> removed ) { zanTrace ( " " , fd ) ; return ZAN_ERR ; } if ( conn -> out_buffer -> length >= ServerG . servSet . buffer_output_size ) { zanTrace ( " " , fd ) ; conn -> overflow = 1 ; } int _length = _send_length ; void * _pos = _send_data ; int _n ; while ( _length > 0 ) { _n = _length >= SW_BUFFER_SIZE_BIG ? SW_BUFFER_SIZE_BIG : _length ; swBuffer_append ( conn -> out_buffer , _pos , _n ) ; _pos += _n ; _length -= _n ; } } if ( reactor -> set ( reactor , fd , SW_EVENT_TCP | SW_EVENT_WRITE | SW_EVENT_READ ) < 0 && ( errno == EBADF || errno == ENOENT ) ) { reactor -> close ( reactor , fd ) ; return ZAN_OK ; } return ZAN_OK ; }
send to client or append to out_buffer
send to client or append to out_buffer
//Reset send buffer, Immediately close the connection. /**
         * close connection.
         */ //Direct send //buffer send //close connection //sendfile to client //send data //connection is closed //connection output buffer overflow //buffer enQueue //listen EPOLLOUT event