Using socket class program hangs?

F

feel52

Below you'll find the code i'm working on.
It's in a button click routine and hangs after 3 or 4 sometimes 5 loops
done, probably in sock.receive(....).
Some code was found here( on google i mean) but the amazing( at least for
me) is that if i run the program step by step or i cancel the loop and run
it by pressing the button again and again it never hangs .
I want to have an infinite loop so my socket keeps on listening until i
press another button.


private void button1_Click(object sender, System.EventArgs e)
{

bool start = true;
while (start)
{
byte[] mydata = new Byte[250];
Socket udpsock = new Socket (AddressFamily.InterNetwork,SocketType.Dgram,
ProtocolType.Udp);
int generalPort=myport;
IPAddress mcastIP = IPAddress.Parse(myip);

IPAddress localIP = IPAddress.Parse(myloc);
EndPoint localEnd = (EndPoint) new IPEndPoint(localIP,generalPort);
udpsock.SetSocketOption(SocketOptionLevel.Socket,
SocketOptionName.ReuseAddress, 1);
mysock.Bind(localEnd);
mysock.SetSocketOption(
SocketOptionLevel.IP,SocketOptionName.AddMembership,
new MulticastOption(mcastIP,localIP));

textBox1.AppendText("Begin datagram:"+"\r\n");


int n = mysock.Receive(data,mydata.Length,SocketFlags.None);

String s =System.BitConverter.ToString(data,0);


textBox1.AppendText(s);
textBox1.AppendText("\r\n");
textBox1.AppendText("End of Datagram"+"\r\n");
mysock.Close();

}

It seems tome that the socket buffer is full so hangs , but. the socket is
closed every time the loop ends..well ,any help will be appreciated.
THANKS.
 
W

William Stacey [MVP]

Why are you using SocketOptionName.ReuseAddress? This smells like it could
be the issue.
Also, why are you creating the socket over and over again in the loop? If
you want a listener, create the socket once and loop on receive.
 
I

Ignacio Machin \( .NET/ C# MVP \)

Hi,

I would change the code a little, in addition to Stacey's opinion I
strongly suggest you two things:

1- Do ALL sockets operations in a worker thread, do not use the UI thread.
2- Do you really need to ReUseAddress and multicast?

What is the intention of the program?

Cheers,
 
F

feel52

William Stacey said:
Why are you using SocketOptionName.ReuseAddress? This smells like it could
be the issue.
Also, why are you creating the socket over and over again in the loop? If
you want a listener, create the socket once and loop on receive.
Thanks,
i'm using Reuse Address because another program receiving from same port,
without it mine raises exception.
Now i will try your second hint.Bye.
 
W

William Stacey [MVP]

Are you sure you want that behavior. Sometime you will get the data, other
times the other app will get the bytes. Is this what you want?
 
W

William Stacey [MVP]

BTW, if you intention is to listen on one thread and send on another, this
reuse will not work as expected. Don't create two sockets, share the same
socket and send on one only and receive on the other only. HTH
 
F

feel52

Ignacio Machin ( .NET/ C# MVP ) said:
Hi,

I would change the code a little, in addition to Stacey's opinion I
strongly suggest you two things:

1- Do ALL sockets operations in a worker thread, do not use the UI thread.
2- Do you really need to ReUseAddress and multicast?

What is the intention of the program?

Cheers,

Well it's hanging as before moving the loop to socket receive.
All I want is to read datagrams ( no sent at all ) incoming and sent to
me in multicast, parse them as the other application does another work
with them,so both must be running at same time. I wrote an application in
delphi7 doing well that , now i'm porting (better trying to..) to C# so i
know that it's a thing that can work without problem.

As i said before it's strange (to me) that if i run step by step everything
works well, i see data arriving on screen in correct way ( i compare them
with the other application), obviously i miss some datagrams as they arrive
more or less 4 or 5 per second and if i run using the loop hangs after
receving fews datagrams.
Thanks again.
 
W

William Stacey [MVP]

I noticed the same thing once. Just has to do with timing when you
stepping. If you do it enouph, you should get the same behavior after many
tries while stepping. I still don't think you will get passed the ReUse
issue. If you have two sockets at same port/IP, you can't control which
socket will receive the data (AFAICT, both will not receive the same bytes.
One or the other will) It is hanging because the other socket gets the data
and probably drops the datagram and your thread is still blocking on a
receive as it never "sees" the bytes. Not sure how this may have worked in
Delphi as both use winsock (unless delphi has another socket
implementation.) You should see the same behavior using winsock api
natively. I have not worked with multicast, so maybe that is answer that
allows both sockets to receive the datagram, but don't think so. Maybe the
Delphi way was two sockets on same port but different IPs using multicast?
I would also try the ms winsock ng. Please let us know if you find the fix.
Cheers!
 
W

William Stacey [MVP]

Also, IMO, a cleaner approach would be to have one socket listening. Get
the datagram and put a copy ref into two queues. Have two other threads.
ThreadA grabs the datagram from the queue and does its thing. ThreadB grabs
the same ref (or a copy of the bytes) and does its thing. You can have
output queue that ThreadC blocks on. When it gets some output, it sends the
reply on ref to same socket.
 
F

feel52

William Stacey said:
I noticed the same thing once. Just has to do with timing when you
stepping. If you do it enouph, you should get the same behavior after many
tries while stepping. I still don't think you will get passed the ReUse
issue. If you have two sockets at same port/IP, you can't control which
socket will receive the data (AFAICT, both will not receive the same bytes.
One or the other will) It is hanging because the other socket gets the data
and probably drops the datagram and your thread is still blocking on a
receive as it never "sees" the bytes. Not sure how this may have worked in
Delphi as both use winsock (unless delphi has another socket
implementation.)

In effect i used some third part components...

You should see the same behavior using winsock api
natively. I have not worked with multicast, so maybe that is answer that
allows both sockets to receive the datagram, but don't think so. Maybe the
Delphi way was two sockets on same port but different IPs using multicast?
I would also try the ms winsock ng. Please let us know if you find the fix.
Cheers!

One more thing,
i noticed now ( it' s two days 'only' i'm facing this problem) that if i
Pause the program, restart it by pressing Step Over ( i'm using Borland
Builder) the counter i put in my code ( i did not write it in my first post)
and that i can see in the Local Variables window kept growing so in effect
the program doesnt hang but , how can i say.... the form hangs and does not
respond to any click and the textbox isn't refreshed by incoming data
(appendtext doesnt work)but in background the socket is still receiving.May
be this can change the point of view of the problem.
Sorry , english is not my mothertongue as you understood , i hope you
understand.
Thanks anyway for your efforts.
 
W

William Stacey [MVP]

You don't want blocking operations in your form. So you want to create
another thread that does the listening and processing. The button will just
start the thread and return so your UI remains active.
I would do something like:
1) create a Server class.
2) That class will contain a thread object. The entry point will be a
private method of your Server class.
3) Create a public Start() method on your server class. Call this to create
the thread and start it.
4) You can create your server object first and pass it udpclient ref or
create the updclient inside the server class. I would encapsulate as much
as possible.
5) Also create Stop() method, etc.

Now in your start button method, just create an instance of Server and start
it. Save this reference in a private form var so you have a ref to it after
the click method returns. This should get you started, you can add a lot
more function to server after you get the general steps working.
 

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

Top