Can Socket.Send not send the whole data ?

  • Thread starter Thread starter enrico sabbadin
  • Start date Start date
E

enrico sabbadin

Hi all,
On a book I read spcket.send might not send the whole data you requested to
send, so you should resend the missing data yourself (see below)
the send method actually has a return value and the docs say:

If you are using a connection-oriented protocol, Send will block until all
of the bytes in the buffer are sent. In nonblocking mode, Send may complete
successfully even if it sends less than the number of bytes in the buffer.
It is your application's responsibility to keep track of the number of bytes
sent and to retry the operation until the application sends the bytes in the
buffer

I noted however I've seen using reflector that the send method of the
network stream implementation just do a plain send without checking for the
return value ..how is that ?

And what is exactly the non blocking mode ? how to set it ?

thank for the explanation
**********
Sending Fixed-Size Messages
When sending fixed-size messages, you must ensure that the entire message is
sent from the Send() method. Don't assume that the complete message was sent
by the TCP system. On a simple Send() method, you might see the following
code:

byte[] data = new byte[1024];
..
..
int sent = socket.Send(data);On the basis of this code, you might be tempted
to presume that the entire 1024-byte data buffer was sent to the remote
device and go on with your program. But this might be a bad assumption.

Depending on the size of the internal TCP buffer and how much data is being
transferred, it is possible that not all of the data supplied to the Send()
method was actually sent. The Send() return value sent indicates how many
bytes of the data were actually sent to the TCP buffer. It is your job to
determine whether all of the data was sent, however. If it wasn't, it is
also your job to try and resend the rest of it. This is often done using a
simple while() statement loop, checking the value returned from the Send()
method against the original size of the data buffer. Of course, if the size
does not match, you must provide a way to send the rest of the data.

The code using this method looks something like this:

int SendData(Socket s, byte[] data)
{
int total = 0;
int size = data.Length;
int dataleft = size;
int sent;
while (total < size)
{
sent = s.Send(data, total, dataleft, SocketFlags.None);
total += sent;
dataleft -= sent;
}
return total;
}
**********

--
(e-mail address removed)
MTS - COM+ - VBCOM - Enterprise Services - Security FAQ
..NET & COM+ books selected list
http://www.sabbasoft.com
"Moving fast is not the same as going somewhere."
 
although I am not a framework/guy, I am a VC/socket guru, so perhaps this
will help, I hope.

the tcp/ip layer implementation doesnt allow sending any size you want in
one call only.
it's just by design.
you are responsible to break down in possibly many calls the whole 'send'
process.

in Windows generally the size of a maximum send is 8192bytes. there fore if
you need to send more than that, you'll have to do multiple sends.
also, at the low level socket programming, you may vary and read what that
threshold is, using ioctl()/socketioctl, and WSA functions...

I hope this will help.

enrico sabbadin said:
Hi all,
On a book I read spcket.send might not send the whole data you requested to
send, so you should resend the missing data yourself (see below)
the send method actually has a return value and the docs say:

If you are using a connection-oriented protocol, Send will block until all
of the bytes in the buffer are sent. In nonblocking mode, Send may complete
successfully even if it sends less than the number of bytes in the buffer.
It is your application's responsibility to keep track of the number of bytes
sent and to retry the operation until the application sends the bytes in the
buffer

I noted however I've seen using reflector that the send method of the
network stream implementation just do a plain send without checking for the
return value ..how is that ?

And what is exactly the non blocking mode ? how to set it ?

thank for the explanation
**********
Sending Fixed-Size Messages
When sending fixed-size messages, you must ensure that the entire message is
sent from the Send() method. Don't assume that the complete message was sent
by the TCP system. On a simple Send() method, you might see the following
code:

byte[] data = new byte[1024];
.
.
int sent = socket.Send(data);On the basis of this code, you might be tempted
to presume that the entire 1024-byte data buffer was sent to the remote
device and go on with your program. But this might be a bad assumption.

Depending on the size of the internal TCP buffer and how much data is being
transferred, it is possible that not all of the data supplied to the Send()
method was actually sent. The Send() return value sent indicates how many
bytes of the data were actually sent to the TCP buffer. It is your job to
determine whether all of the data was sent, however. If it wasn't, it is
also your job to try and resend the rest of it. This is often done using a
simple while() statement loop, checking the value returned from the Send()
method against the original size of the data buffer. Of course, if the size
does not match, you must provide a way to send the rest of the data.

The code using this method looks something like this:

int SendData(Socket s, byte[] data)
{
int total = 0;
int size = data.Length;
int dataleft = size;
int sent;
while (total < size)
{
sent = s.Send(data, total, dataleft, SocketFlags.None);
total += sent;
dataleft -= sent;
}
return total;
}
**********

--
(e-mail address removed)
MTS - COM+ - VBCOM - Enterprise Services - Security FAQ
.NET & COM+ books selected list
http://www.sabbasoft.com
"Moving fast is not the same as going somewhere."
 
Hi socket guru, thank for you answer :)

If I stay under that size threshold am I guaranteed that I'll need only one
send ?

What happens exactly if I send more than that thresold ? I get an error or
the integer returned by the send method is less than the requested size to
send ?

If the latter apply, to be on the safe side, should I always wrap my send
as shown below , regardless of the size of the message and regardless if I'm
using blocking or non blocking sockets ?

Does using blocking or non blocking sockets make any difference to this
picture somehow ?

Thank again for you support

int SendData(Socket s, byte[] data)
andrea catto' said:
although I am not a framework/guy, I am a VC/socket guru, so perhaps this
will help, I hope.

the tcp/ip layer implementation doesnt allow sending any size you want in
one call only.
it's just by design.
you are responsible to break down in possibly many calls the whole 'send'
process.

in Windows generally the size of a maximum send is 8192bytes. there fore if
you need to send more than that, you'll have to do multiple sends.
also, at the low level socket programming, you may vary and read what that
threshold is, using ioctl()/socketioctl, and WSA functions...

I hope this will help.

enrico sabbadin said:
Hi all,
On a book I read spcket.send might not send the whole data you requested to
send, so you should resend the missing data yourself (see below)
the send method actually has a return value and the docs say:

If you are using a connection-oriented protocol, Send will block until all
of the bytes in the buffer are sent. In nonblocking mode, Send may complete
successfully even if it sends less than the number of bytes in the buffer.
It is your application's responsibility to keep track of the number of bytes
sent and to retry the operation until the application sends the bytes in the
buffer

I noted however I've seen using reflector that the send method of the
network stream implementation just do a plain send without checking for the
return value ..how is that ?

And what is exactly the non blocking mode ? how to set it ?

thank for the explanation
**********
Sending Fixed-Size Messages
When sending fixed-size messages, you must ensure that the entire
message
is
sent from the Send() method. Don't assume that the complete message was sent
by the TCP system. On a simple Send() method, you might see the following
code:

byte[] data = new byte[1024];
.
.
int sent = socket.Send(data);On the basis of this code, you might be tempted
to presume that the entire 1024-byte data buffer was sent to the remote
device and go on with your program. But this might be a bad assumption.

Depending on the size of the internal TCP buffer and how much data is being
transferred, it is possible that not all of the data supplied to the Send()
method was actually sent. The Send() return value sent indicates how many
bytes of the data were actually sent to the TCP buffer. It is your job to
determine whether all of the data was sent, however. If it wasn't, it is
also your job to try and resend the rest of it. This is often done using a
simple while() statement loop, checking the value returned from the Send()
method against the original size of the data buffer. Of course, if the size
does not match, you must provide a way to send the rest of the data.

The code using this method looks something like this:

int SendData(Socket s, byte[] data)
{
int total = 0;
int size = data.Length;
int dataleft = size;
int sent;
while (total < size)
{
sent = s.Send(data, total, dataleft, SocketFlags.None);
total += sent;
dataleft -= sent;
}
return total;
}
**********

--
(e-mail address removed)
MTS - COM+ - VBCOM - Enterprise Services - Security FAQ
.NET & COM+ books selected list
http://www.sabbasoft.com
"Moving fast is not the same as going somewhere."
 
some more info ..
I've tried both a blocking and a non blocking socket.
In the first case the send blocks when the buffer is full till the
application on the other side pulls some data.
In the second case and exception is thrown ..
I could not reproduce a situation where the send returns with a value that
is less than the required amount of dat to send.
I question myself the real usefullness of the sample code I showed in my
previous post picked up from the book

C# Network Programming
by Richard Blum



enrico sabbadin said:
Hi socket guru, thank for you answer :)

If I stay under that size threshold am I guaranteed that I'll need only one
send ?

What happens exactly if I send more than that thresold ? I get an error or
the integer returned by the send method is less than the requested size to
send ?

If the latter apply, to be on the safe side, should I always wrap my send
as shown below , regardless of the size of the message and regardless if I'm
using blocking or non blocking sockets ?

Does using blocking or non blocking sockets make any difference to this
picture somehow ?

Thank again for you support

int SendData(Socket s, byte[] data)
andrea catto' said:
although I am not a framework/guy, I am a VC/socket guru, so perhaps this
will help, I hope.

the tcp/ip layer implementation doesnt allow sending any size you want in
one call only.
it's just by design.
you are responsible to break down in possibly many calls the whole 'send'
process.

in Windows generally the size of a maximum send is 8192bytes. there fore if
you need to send more than that, you'll have to do multiple sends.
also, at the low level socket programming, you may vary and read what that
threshold is, using ioctl()/socketioctl, and WSA functions...

I hope this will help.

enrico sabbadin said:
Hi all,
On a book I read spcket.send might not send the whole data you
requested
to
send, so you should resend the missing data yourself (see below)
the send method actually has a return value and the docs say:

If you are using a connection-oriented protocol, Send will block until all
of the bytes in the buffer are sent. In nonblocking mode, Send may complete
successfully even if it sends less than the number of bytes in the buffer.
It is your application's responsibility to keep track of the number of bytes
sent and to retry the operation until the application sends the bytes
in
the
buffer

I noted however I've seen using reflector that the send method of the
network stream implementation just do a plain send without checking
for
the
return value ..how is that ?

And what is exactly the non blocking mode ? how to set it ?

thank for the explanation
**********
Sending Fixed-Size Messages
When sending fixed-size messages, you must ensure that the entire
message
is
sent from the Send() method. Don't assume that the complete message
was
sent
by the TCP system. On a simple Send() method, you might see the following
code:

byte[] data = new byte[1024];
.
.
int sent = socket.Send(data);On the basis of this code, you might be tempted
to presume that the entire 1024-byte data buffer was sent to the remote
device and go on with your program. But this might be a bad assumption.

Depending on the size of the internal TCP buffer and how much data is being
transferred, it is possible that not all of the data supplied to the Send()
method was actually sent. The Send() return value sent indicates how many
bytes of the data were actually sent to the TCP buffer. It is your job to
determine whether all of the data was sent, however. If it wasn't, it is
also your job to try and resend the rest of it. This is often done
using
a
simple while() statement loop, checking the value returned from the Send()
method against the original size of the data buffer. Of course, if the size
does not match, you must provide a way to send the rest of the data.

The code using this method looks something like this:

int SendData(Socket s, byte[] data)
{
int total = 0;
int size = data.Length;
int dataleft = size;
int sent;
while (total < size)
{
sent = s.Send(data, total, dataleft, SocketFlags.None);
total += sent;
dataleft -= sent;
}
return total;
}
**********

--
(e-mail address removed)
MTS - COM+ - VBCOM - Enterprise Services - Security FAQ
.NET & COM+ books selected list
http://www.sabbasoft.com
"Moving fast is not the same as going somewhere."
 
Back
Top