Archived

This topic is now archived and is closed to further replies.

ftsf

SDLNet Server

Recommended Posts

i'm trying to make a server for my network game, but the server only registers the first client, all clients after that are ignored until the subsequent client quits. is this a problem with my code? or something with SDLNet, or could it be because i am running all the clients on the same computer?
  
while(true) {
    if(nClients < nMaxClients) {
        // search for a free client

        for(x = 0; x <= nMaxClients; x++) {
            if(client[x].open == false)
                break;
        }
        client[x].sock = SDLNet_TCP_Accept(listeningSocket);
        if(client[x].sock != NULL) {
            client[x].open = true;
            nClients++;
        }
    }
    // Read client messages

    for(x = 0; x < nMaxClients; x++) {
        if(client[x].open == true) {
            unsigned short cmd;
            int len = SDLNet_TCP_Recv(client[x].sock, &cmd, 2);
            if(len) {
                if(cmd == SP_NAME) {
                    SDLNet_TCP_Recv(client[x].sock, client[x].name, 15);
                } else if(cmd == SP_QUIT) {
                    SDLNet_TCP_Close(client[x].sock);
                    client[x].open = false;
                    nClients--;
                }
            }
        }
    }
}
  
[edited by - Kylotan on July 28, 2002 1:28:25 PM]

Share this post


Link to post
Share on other sites
I hope you don''t mind, but I edited your message to try and format the code more clearly.

Unfortunately I can''t get to the SDL_Net documentation page at the moment, so this will have to be idle speculation I''m afraid. Are all these calls blocking or not? I''m assuming they''re not by the way you coded it all, but if they are, new connections might be timing out while the server is waiting for the existing connection to send data, or something like that.

How large is nMaxClients? And shouldn''t x <= nMaxClients be x < nMaxClients? And how did you initialise the listening socket?

[ MSVC Fixes | STL | SDL | Game AI | Sockets | C++ Faq Lite | Boost | Asking Questions | Organising code files ]

Share this post


Link to post
Share on other sites
Heya,
it could be that you always listen on the first client.

SDL TCP Sockets are blocking, means you read till you recieve something.

Before you read from a Socket you need to check if the Socket has activity.

SDL_Net provides a function to check a SocketSet for activity, i couldnt find a similar function for a single socket.

The thing i did was:
- add socket to socketSet,
- check socketSet for activity,
- if activ then read
else check next socket

if you want, i can email you my project, it should be a 'Framework' for network games, but its far from being very useful hehe.

void Server::listenOnClients( void )
{
Client *pClient = NULL;
void *pvPtr = NULL;;
int recvBytes;
int nActiveSockets;
SDLNet_SocketSet tempSocketSet;

vector<Client*>::iterator itr;


do {
tempSocketSet = NULL;

nActiveSockets = 0;
recvBytes = 0;
pvPtr = malloc(Net::PACKETLEN);
pClient = NULL;

tempSocketSet = SDLNet_AllocSocketSet( 5 );

for( itr = m_clientPtrVector.begin(); itr != m_clientPtrVector.end(); ++itr ) {
pClient = (*itr);

SDLNet_TCP_AddSocket( tempSocketSet, pClient->m_socket.getConnectedSocket() );

nActiveSockets = SDLNet_CheckSockets( tempSocketSet, m_iCheckSocketTimeOut );

if( nActiveSockets < 0) {
cerr << "Fehler bei SDLNet_CheckSockets() !" << endl;
} else if( nActiveSockets == 0 ) {
SDLNet_TCP_DelSocket( tempSocketSet, pClient->m_socket.getConnectedSocket() );
continue;
}

recvBytes = SDLNet_TCP_Recv( pClient->m_socket.getConnectedSocket(),
pvPtr, (int)Net::PACKETLEN );

if( recvBytes < 0 ) {
// Keine Verbindung mehr zum Client - aus der Liste entfernen

cout << "Verbindung zu Client [" << (int)pClient->m_iId << "] verloren!\n";

// RemovePlayer meldung an alle anderen Clients schicken

createRemovePlayerPacket( pvPtr );
processPacket( pClient->m_iId, pvPtr );

// Socket schliessen und aus dem socket set entfernen

SDLNet_TCP_Close( pClient->m_socket.getConnectedSocket() );
SDLNet_TCP_DelSocket( tempSocketSet, pClient->m_socket.getConnectedSocket() );

itr = m_clientPtrVector.erase( itr );
// itr zeigt jetzt schon auf den nächsten Client in der Liste

// er muss dekrementiert werden um bei der nächsten Iteration

// nicht eins zuweit zu sein!

itr--;

cout << "Client wurde aus der Liste entfernt, anzahl clients:"
<< static_cast<int>( m_clientPtrVector.size() ) << endl;
continue;

} else if ( recvBytes == 0 ) {
// Client hat nichts geschickt -> ignorieren

// da diese Funktion nur bei socket Aktivität ausgeführt wird,

// sollten nie 0 bytes empfangen werden können

cout << "[" << pClient->m_iId << "] hat 0 bytes geschickt..?" << endl;
} else {
// Es sind Daten im Buffer vorhanden.

// zuerst die Daten auslesen, mit der Id des Clients versehen

// und an alle Clients, ausser den sender, senden.

processPacket( pClient->m_iId, pvPtr );
}

SDLNet_TCP_DelSocket( tempSocketSet, pClient->m_socket.getConnectedSocket() );
}
delete pvPtr;
SDLNet_TCP_DelSocket( tempSocketSet, pClient->m_socket.getConnectedSocket() );
SDLNet_FreeSocketSet( tempSocketSet );

} while ( recvBytes > 0 );
}
[\source]


if god gave us the source code, we could change the world!


[edited by - Lazzar on September 17, 2003 7:26:21 AM]

[edited by - Lazzar on September 17, 2003 7:48:58 PM]

Share this post


Link to post
Share on other sites