Exemple #1
0
int TcpServer::processSend()
{
    char *buffer;
    size_t size, sent;
    if (this->stopping) return 0;


    //TODO: I find it dramatic to iterate over all the connections. Maybe 
    //      I could create one eventFd for each connection to notify that
    //      Data is ready to be sent.
    for (auto it = clientList.begin(); it != clientList.end(); it++)
    {
        TcpClient* client = it->second;
        while ((size = client->getTxData(&buffer)) > 0)
        {
            sent = client->getSocket()->send(buffer, size);    
            if (sent == -1)
            {
                if (errno != EAGAIN)
                {
                    LOG("write error. returned " << errno);
                    abort();
                }
                //if EAGAIN, we stop sending and we will get notified by EPOLL when we are ready again
            }
            else if (sent == 0)
            {
                client->onDisconnected();
                clientList.erase(it);
                delete it->second;
                break;
            }
            else
            {
                // this will move us to the next buffer or further in current if partially sent.
                client->onDataSent(sent);
            }
        }

        // after we are finished sending the tx queue, check if the client is failed and close the connection
        if (client->mFailed)
        {
            client->getSocket()->close();
            client->onDisconnected();
            delete client;
            clientList.erase(it);
        }
    }


}
Exemple #2
0
int TcpServer::processReceive(int socket)
{
    auto it = clientList.find(socket);
    if (it == clientList.end()) return 0;
    
    TcpClient* client = it->second;

    char tmpBuffer[1024];  //TODO: should get a buffer from a buffer pool
    size_t n = 1;
    while (n > 0)
    {
        if (this->stopping)
        {
            n = 0;
            break;
        }
        n = client->getSocket()->read((char*)&tmpBuffer[0], 1024);

        if (n == 0)
        {
            client->onDisconnected();
            clientList.erase(it);
            delete client;
        }
        else if (n == -1)
        {
            n = 0;
            if (errno == ECONNRESET)
            {
                client->onDisconnected();
                clientList.erase(it);
                delete client;
            }
            else 
            {
                if (errno != EAGAIN)
                {
                    LOG("Read error. Returned " << errno);
                    abort();
                }
            }
            break;
        }
        else
        {
            client->onReceive((char*)&tmpBuffer[0], n);            
        }
    }
    
    return n;
}