.NET Socket

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

A few days back I was just coding for a basic TCP/IP Client to send and
recieve buffer across network.

I encountered a problem in receiving data through receive method.

I am sharing this with community as it may help others, who are novice is
..NET socket programming.

I searched all over net for samples and found all over (including MSDN).
Blocking mode was enough for me so I coded my receive as:

<CODE>

Byte[] bytesReceived = new Byte[256];
do
{
bytes = s.Receive(bytesReceived);
strReceived += Encoding.ASCII.GetString(bytesReceived, 0, bytes);
}
while (bytes > 0);

</CODE>

But later I noticed that if in last iteration the bytes come to be less than
256 i.e. when I have received all data the next receive call causes the
execution to block as receive has nothing to receive.

Realizing that I changed my code to:

<CODE>

Byte[] bytesReceived = new Byte[256];
do
{
bytes = s.Receive(bytesReceived);
strReceived += Encoding.ASCII.GetString(bytesReceived, 0, bytes);
}
while (bytes != 256);

</CODE>

It worked fine for all my real scenarios. But I kept thinking that it will
also cause problem if the bytes to be received is multiple of 256 chunks. In
that case it will also block execution when last time it calls receives
method.

Finally I got something better:

<CODE>

Byte[] bytesReceived = new Byte[256];
while (s.Available)
{
bytes = s.Receive(bytesReceived);
strReceived += Encoding.ASCII.GetString(bytesReceived, 0, bytes);
}

</CODE>

I thought it would be appropriate to change my do-while loop to while. But I
did a mistake there. As sometimes s.Available returns 0 even if receive is
able to receive data. And so in all such cases my loop to recieve data got
bypassed.
As I analyzed this and guessed reason was the data chunk was not available
when s.Available is called but since receive is a blocking call it waits for
data arrival and finally returns with data.

So, finally I changed the code to following and it worked fine.

<CODE>

Byte[] bytesReceived = new Byte[256];
do
{
bytes = s.Receive(bytesReceived);
strReceived += Encoding.ASCII.GetString(bytesReceived, 0, bytes);
}
while (s.Available);

</CODE>

Regards,
Rahul Anand
 
Rahul Anand said:
<CODE>

Byte[] bytesReceived = new Byte[256];
do
{
bytes = s.Receive(bytesReceived);
strReceived += Encoding.ASCII.GetString(bytesReceived, 0, bytes);
}
while (bytes > 0);

</CODE>

But later I noticed that if in last iteration the bytes come to be less than
256 i.e. when I have received all data the next receive call causes the
execution to block as receive has nothing to receive.

So the problem you're trying to solve is preventing a call to
Socket.Receive from blocking indefinitely?

If so, you're approaching the problem incorrectly. You should use the
above code in a worker thread, *allowing* it to block indefinitely. You
can call Socket.Shutdown in another thread to interrupt that blocking call.
 
=?Utf-8?B?UmFodWwgQW5hbmQ=?= said:
Byte[] bytesReceived = new Byte[256];
do
{
bytes = s.Receive(bytesReceived);
strReceived += Encoding.ASCII.GetString(bytesReceived, 0, bytes);
}
while (s.Available);

IIRC available returns true on disconnect too and you could get stuck in a loop.

But polling like this is typically very bad if you are using non blocking mode. If you are using
blocking, then Receive will return 0 when disconnected and you need to check for that.

You might also check out Indy - it implements a lot of this stuff automatically for you, and its
free:
http://www.indyproject.org/


--
Chad Z. Hower (a.k.a. Kudzu) - http://www.hower.org/Kudzu/
"Programming is an art form that fights back"

Empower ASP.NET with IntraWeb
http://www.atozed.com/IntraWeb/
 
Cool Guy said:
Rahul Anand said:
<CODE>

Byte[] bytesReceived = new Byte[256];
do
{
bytes = s.Receive(bytesReceived);
strReceived += Encoding.ASCII.GetString(bytesReceived, 0, bytes);
}
while (bytes > 0);

</CODE>

But later I noticed that if in last iteration the bytes come to be less than
256 i.e. when I have received all data the next receive call causes the
execution to block as receive has nothing to receive.

So the problem you're trying to solve is preventing a call to
Socket.Receive from blocking indefinitely?

If so, you're approaching the problem incorrectly. You should use the
above code in a worker thread, *allowing* it to block indefinitely. You
can call Socket.Shutdown in another thread to interrupt that blocking call.

In my case the blocking mode is fine but I do not want the receive to block
unnecessarily (i.e. it blocks till timeout if there is not data available).

I was just discussing this problem on how to exit the while loop after
receiving all available data.

I hope now it will be more clear now.

Just want to know whether my approach is right or I can do something better.
 
=?Utf-8?B?UmFodWwgQW5hbmQ=?= said:
wrote in news:[email protected]:
Byte[] bytesReceived = new Byte[256];
do
{
bytes = s.Receive(bytesReceived);
strReceived += Encoding.ASCII.GetString(bytesReceived, 0, bytes);
}
while (s.Available);

IIRC available returns true on disconnect too and you could get stuck in a loop.

But polling like this is typically very bad if you are using non blocking mode. If you are using
blocking, then Receive will return 0 when disconnected and you need to check for that.

You might also check out Indy - it implements a lot of this stuff automatically for you, and its
free:
http://www.indyproject.org/


--
Chad Z. Hower (a.k.a. Kudzu) - http://www.hower.org/Kudzu/
"Programming is an art form that fights back"

Empower ASP.NET with IntraWeb
http://www.atozed.com/IntraWeb/

Thanks chad for your comments. I tried to disconnect the server after
sending the request and found it does not cause receive to return zero, it
throws a SocketException. I really want to know whether there is any
situation when recieve returns 0 and Avalible returns some value > 0.

Please post some sample code to achieve this. Your help and time is
appreciated.
 
=?Utf-8?B?UmFodWwgQW5hbmQ=?= said:
Thanks chad for your comments. I tried to disconnect the server after
sending the request and found it does not cause receive to return
zero, it throws a SocketException. I really want to know whether there
is any situation when recieve returns 0 and Avalible returns some
value > 0.

Winsock returns 0 for sure if its a graceful disconnect. I dont remember what SNS does offhand.
How did you disconnect the server to do this test - a hard disconnect or a soft one?
Please post some sample code to achieve this. Your help and time is
appreciated.

I dont work with SNS directly. I can easily post Indy code if you want. Indy is open source and
therefore free. It will make your code a lot sipmler - Indy provides a much higher abstraction layer
from the network interface, while SNS is just a object wrapper nearly 1:1 for the stack.


--
Chad Z. Hower (a.k.a. Kudzu) - http://www.hower.org/Kudzu/
"Programming is an art form that fights back"

Get your ASP.NET in gear with IntraWeb!
http://www.atozed.com/IntraWeb/
 
Chad Z. Hower aka Kudzu said:
Winsock returns 0 for sure if its a graceful disconnect. I dont remember what SNS does offhand.
How did you disconnect the server to do this test - a hard disconnect or a soft one?

Hi Chad,

I disconnected the server by calling Close method on socket.
I have also referred MSDN on this and there it is written like this:

If no data is available for reading, the Receive method will block until
data is available. If you are in non-blocking mode, and there is no data
available in the in the protocol stack buffer, the Receive method will
complete immediately and throw a SocketException . You can use the Available
property to determine if data is available for reading. __When Available is
non-zero, retry the receive operation__.

If you are using a connection-oriented Socket , the Receive method will read
as much data as is available, up to the size of the buffer. If the remote
host shuts down the Socket connection with the Shutdown method, *and* all
available data has been received, the Receive method will complete
immediately and return zero bytes.

From this I assume till there is data bytes available Receive will not
return 0. And hence Available will work fine.

Your help is appreciated.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top