   SDL_net, Safe reading of messages
  I am currently writing a server (and database) and I've run into a potential problem.  It hasn't happened yet, but the threat of it is so severe that I cannot continue without resolving it.Normal packets are of the format <header><size><data>.  The server reads the header (always 2 bytes) to identify the packet and then reads and stores size bytes into a struct.  At first this seemed logical, until I realized that SDL_Net does not provide a means (so far as I can see) to run asynchronous sockets, which I've always preferred.  A malicious client could send a blank packet, or a packet containing a valid header and size, but no actual data.  The SDL_TCP_Recv() function would wait for the data, but the client may well never send it and never close the connection.  All of the clients are connected on the same thread, so each one behind that client will have to wait for it to complete - in essence, it can shut down the server.Why oh why is SDL_TCP_Recv() blocking/synchronous?  I'd much prefer it to just pad the missing data - as TCP packets are already guaranteed to arrive together and the extra security really only creates a vulnerability.How would one receive messages asynchronously?//this is a snippet containing all the major parts of the functionunsigned short mlength;int length;unsigned int header;Connection* connect;char message[1024];while(true){length=SDLNet_TCP_Recv(connect->socket,&header,4);if(length){connect->lping=SDL_GetTicks();if(SDLNet_TCP_Recv(connect->socket,&mlength,2)<0)continue;//Loop if no headerif(SDLNet_TCP_Recv(connect->socket,&message,std::min<unsigned short>(mlength,1024))<0)continue;//Loop if no data//use packet}else if(length<0){connect->lping=0;break;}}struct Connection{TCPsocket socket;IPaddress* remoteip;SDL_Thread* thread_communication;unsigned short port,lping;unsigned short kill(void);};
  SDLNet_TCP_Recv and SDLNet_TCP_Send both do you a favor and grab all of the buffer in one go unlike standard sockets so you do not have to contain them in a loop.For error checking on the receiving side, if the call to SDLNet_SocketReady returned true and recv returned <= 0 it is usually safe to assume the other side closed the connection. This causes the socket to show ready but you don't get anything from it. Don't forget to use SDLNet_CheckSockets on the socket set first or socketready won't return a good value;For error checking on the sending side, if you don't actually send the number of bytes you specified, it is usually safe to assume the other side closed. That is according to the documentation anyway.If this isn't enough for you then I would check out NET2 on www.gameprogrammer.com (the site seems to be down right now). It gives you an event driven, threaded version of the SDL_net library.   ;Quote:Original post by ZouflainWhy oh why is SDL_TCP_Recv() blocking/synchronous?So that logic is simplified - you know exactly what you're going to get.Quote:I'd much prefer it to just pad the missing data - as TCP packets are already guaranteed to arrive togetherNo, they're not. You are given no such guarantees about TCP about anything arriving together. Indeed, at the TCP level there is no such thing as a packet. Whatever data you get, you get in order, but that's essentially the only guarantee you get.Quote:and the extra security really only creates a vulnerability.That makes no sense.   