tags:

views:

110

answers:

2

I'm using Perl sockets in AIX 5.3, Perl version 5.8.2

I have a server written in Perl sockets. There is a option called "Blocking", which can be set to 0 or 1. When I use Blocking => 0 and run the server and client send data (5000 bytes), I am able to recieve only 2902 bytes in one call. When I use Blocking => 1, I am able to recieve all the bytes in one call.

Is this how sockets work or is it a bug?

+2  A: 

Blocking means that the socket waits till there is data there before returning from a recieve function. It's entirely possible there's a tiny wait on the end as well to try to fill the buffer before returning, or it could just be a timing issue. It's also entirely possible that the non-blocking implementation returns one packet at a time, no matter if there's more than one or not. In short, no it's not a bug, but the specific 'why' of it is the old cop-out "it's implementation specific".

Matthew Scharley
So, How do i fix this issue?Because if i send small amount of data, I need to set Blocking => 0 and if I send large amounts of data , I need to set Blocking => 1, but then I can't sent small data..:(
someguy
It isn't an 'issue', really. You just need to call the `recieve` or `recv` (it's been a while since I've used Perl) more than once to fetch the rest of the data, and use an extra buffer inside you program to store up all the recieved data before processing it.
Matthew Scharley
I m using sysread.Could that be causing a issue?
someguy
+6  A: 

This is a fundamental part of sockets - or rather, TCP, which is stream-oriented. (UDP is packet-oriented.)

You should never assume that you'll get back as much data as you ask for, nor that there isn't more data available. Basically more data can come at any time while the connection is open. (The read/recv/whatever call will probably return a specific value to mean "the other end closed the connection.)

This means you have to design your protocol to handle this - if you're effectively trying to pass discrete messages from A to B, two common ways of doing this are:

  • Prefix each message with a length. The reader first reads the length, then keeps reading the data until it's read as much as it needs.
  • Have some sort of message terminator/delimiter. This is trickier, as depending on what you're doing you may need to be aware of the possibility of reading the start of the next message while you're reading the first one. It also means "understanding" the data itself in the "reading" code, rather than just reading bytes arbitrarily. However, it does mean that the sender doesn't need to know how long the message is before starting to send.

(The other alternative is to have just one message for the whole connection - i.e. you read until the the connection is closed.)

Jon Skeet
Thanx Jon, it worked.
someguy