May 16, 2024, 08:56:30 PM

News:

Own IWBasic 2.x ? -----> Get your free upgrade to 3.x now.........


recv ignoring big buffer from socket

Started by JoaoAfonso, October 02, 2008, 06:12:12 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

JoaoAfonso

Good evening.
I am having a small bug in my program I want to get rid off. It consist on a server where multiple clients can be connected. If clients decide to send big packages, it will overflow the system and can break the program.
How should I use the recv() function in order to ignore info bigger than the defined buffer?

sub ClientEvent
INT a,x,pos1,tempint,temp
STRING info,accao
INT ReceivedBytes
ISTRING bufor[32768]
for x=1 to MaxSockets-1
Bufor=chr$(0)
if SockTable[x]>0
ReceivedBytes=recv(SockTable[x],Bufor,4096,0)


If I send a packet with, lets say, 5000 bytes, server will receive immediately one of 4096 and then another one with 904. What should I do to, if receiving more than the 4096, ignore the other 904? Searched in google the available flags for the function, but none was specific to this, so there is something escaping me.

Thanks in advance
JoÃÆ'ƒÂÃ,£o Afonso
Viriato
-----------------
Iberia MUD
www.iberiamud.com
iberiamud.com:5900

sapero

Pass a temporary buffer for recv(), and if the destination buffer has some space left, just append the received data. When you fill the destination buffer with 4096 bytes, do not quit from your receive loop, read the data from server to temporary buffer and nothing else, until you receive all data.

char tempbufer[2048] /* default socket buffer size in windows: getsockopt SO_RCVBUF*/
appendPointer = Client.Bufer
bytesLeft = 4096


while true
   bytesReceived = recv(socket, &tempbufer, 2048, 0)
   if (bytesReceived < 1) then handle error

   if bytesLeft
      ' number of bytes to copy = MIN(bytesReceived, bytesLeft)
      bytesToCopy = bytesReceived
      if (bytesToCopy > bytesLeft) then bytesToCopy = bytesLeft

      CopyMemory(appendPointer, tempbufer, bytesToCopy)
      appendPointer += bytesToCopy
      bytesLeft -= bytesToCopy
   else
      ' no space in client buffer; ignore data
   endif
endwhile

JoaoAfonso

Hmm... but that do not prevent clients to flood the server, I believe... right? That is my main objective
JoÃÆ'ƒÂÃ,£o Afonso
Viriato
-----------------
Iberia MUD
www.iberiamud.com
iberiamud.com:5900

sapero

If you want to stop any receiving after you receive N-bytes, use shutdown function:
shutdown(socket, SD_RECEIVE)
Or call WSAAsyncSelect again, without FD_READ flag.

JoaoAfonso

I want to stop receiving after receiving N-bytes, but dont want to close the socket and want to receive the next packages coming from that socket other than that big one (to continue de routine of checking each client input).
If I use shutdown, how to restart receiving from the same socket without closing it?
JoÃÆ'ƒÂÃ,£o Afonso
Viriato
-----------------
Iberia MUD
www.iberiamud.com
iberiamud.com:5900

sapero

It's not possible with Microsoft sockets. Choose the first method with temporary buffer, or extend your protocol with a packet that tells the server to stop sending data {current, with id or name}, or while initializing data transfer, send a packet with client buffer size, so server will send not more than client can store. Ofcourse if you have access to server code - like socket application or php script.

JoaoAfonso

Hmm... not sure I got everything you told me.

Server is my program. Clients will connect to it, so I should be able to control and/or discard the info sent to me, I believe. Problem is if bad intentioned persons connect to my server and flood it in order to break it, I should be able to avoid it. My first solution is to just read first X bytes of information sent by each client, ignoring the rest (otherwise, they can keep flooding).
JoÃÆ'ƒÂÃ,£o Afonso
Viriato
-----------------
Iberia MUD
www.iberiamud.com
iberiamud.com:5900

sapero

Ah so, then you should design client application to not send more than X bytes. If you detect that someone is sending more (reverser?), you can simply close connection and set time ban to client IP.

JoaoAfonso

It's a game I am doing, and the good of this kind of games (text based) is that anyone can connect using, as example, telnet, so no need to have a specific client. So what I really want is just get rid of extra data besides, lets say, 500 characters. There is just one or two chances of a player write so much data, a third one will be to break my server, and I want to prevent that. Also, if each client can send too much data, it will slow the game as well.
So to this last problem, I want to limit to 500 chars and ignore the rest (for each package). For a continuous sent of packages, I have already a solution.
JoÃÆ'ƒÂÃ,£o Afonso
Viriato
-----------------
Iberia MUD
www.iberiamud.com
iberiamud.com:5900