UDP Listen on same port by two apps at same time

  • Thread starter Thread starter mBird
  • Start date Start date
M

mBird

I wrote a service that listens for broadcast messages from my firewall (UDP
snmp trap messages) and parses and puts the data in an database.

I'd also like to write an app that is a simple form that can listen in when
it runs (so I can see messages in a form as they occur.)

So I need the ability to listen to a UDP port with two apps at the same time
(the service and my app). But when I do that I get an error:
System.Net.Sockets.SocketException: Only one usage of each socket address
(protocol/network address/port) is normally permitted
at System.Net.Sockets.Socket.Bind(EndPoint localEP)
at UdpReceive.Class1.StartReceiveFrom() in
c:\myprojects\dotnet\cs\networking

Is it possible to listen to the same port with two apps at once?

Thank you

p.s. One way I could do this is to use a packet driver and something like
WinPCap and just grab the frames from any app I have -- but I'd like to try
this strictly from the DotNet Framework and C#.
 
U¿ytkownik "mBird said:
I wrote a service that listens for broadcast messages from my firewall (UDP
snmp trap messages) and parses and puts the data in an database.

I'd also like to write an app that is a simple form that can listen in when
it runs (so I can see messages in a form as they occur.)

So I need the ability to listen to a UDP port with two apps at the same time
(the service and my app). But when I do that I get an error:
System.Net.Sockets.SocketException: Only one usage of each socket address
(protocol/network address/port) is normally permitted
at System.Net.Sockets.Socket.Bind(EndPoint localEP)
at UdpReceive.Class1.StartReceiveFrom() in
c:\myprojects\dotnet\cs\networking

Is it possible to listen to the same port with two apps at once?

Thank you

p.s. One way I could do this is to use a packet driver and something like
WinPCap and just grab the frames from any app I have -- but I'd like to try
this strictly from the DotNet Framework and C#.
I think you can't (Or maybe you shouldn't). It's incompatible with UDP
standard.
 
Hi,

mBird said:
I wrote a service that listens for broadcast messages from my firewall (UDP
snmp trap messages) and parses and puts the data in an database.

I'd also like to write an app that is a simple form that can listen in when
it runs (so I can see messages in a form as they occur.)

So I need the ability to listen to a UDP port with two apps at the same time
(the service and my app). But when I do that I get an error:
System.Net.Sockets.SocketException: Only one usage of each socket address
(protocol/network address/port) is normally permitted
at System.Net.Sockets.Socket.Bind(EndPoint localEP)
at UdpReceive.Class1.StartReceiveFrom() in
c:\myprojects\dotnet\cs\networking

Is it possible to listen to the same port with two apps at once?

Try to set the following option before calling bind :
_socket.SetSocketOption(SocketOptionLevel.Socket,
SocketOptionName.ReuseAddress, 1);


HTH,
greetings
 
I would have thought the best method would be to have the service send a message to your form.
 
Is it possible to listen to the same port with two apps at once?

Don't bind the port, just receive on it?
 
Hi,

BMermuys said:
Hi,



Try to set the following option before calling bind :
_socket.SetSocketOption(SocketOptionLevel.Socket,
SocketOptionName.ReuseAddress, 1);

Some explenation.

You must always bind before you can receive. For connection-oriented
sockets (TCP) this might be done implicitly by a connect call or explicitly
by calling bind before calling listen.

For connection-less oriented sockets (UDP):
To receive unicast udp, you bind to a local addr/port to which udp packets
are sent.

To receive multicast udp, eg sent to 239.255.255.250:1900, you add the ip
address as a multicast group(socketoptions) and then bind to the local port
1900.

Bind allows only one process to bind to one local addr/port pair.

This is ussally fine, but multicast means for everyone, so it makes sense
that multiple processes (aplications) can receive them. SO_REUSEADDR makes
this possible. It allows multiple processes to receive the same broadcast
packet.

Note that even when using the SO_REUSEADDR option unicast udp packets will
only be received by one socket. This because unicast means only one.
Usually the last bounded socket receives it.

Now to set the socket option SO_REUSEADDR in c# call:

Socket _socket;
....
_socket.SetSocketOption(SocketOptionLevel.Socket,
SocketOptionName.ReuseAddress, 1);
....

1 only indicates true.

When you set this option, you indicate that another process may bind to the
same local addr/port.


HTH,
Greetings
 
Hi --

Thanks for the info --

I tried using the SetSocketOption. To test it I did:
-Created a test listener
-Launched the testlistener.exe twice (so now two apps listening).

Both launched OK (so no longer get errror message "Only one usage of each
socket address (protocol/network address/port) is normally permitted")

But only one app instance sees UDP messages (they are simple console apps
and one sees and prints my UPD messages while the other apps instance just
sits there and does nothing)???

Here is the code for a test client I used -- any ideas greatly appretiated!
Thanks

public void StartReceiveFrom()
{
IPHostEntry localHostEntry;

try
{
Socket soUdp =
new Socket(AddressFamily.InterNetwork, SocketType.Dgram,
ProtocolType.Udp);
soUdp.SetSocketOption(SocketOptionLevel.Socket,
SocketOptionName.ReuseAddress, 1);

try
{
localHostEntry = Dns.GetHostByName(Dns.GetHostName());
}
catch(Exception)
{
Console.WriteLine("Local Host not found");
return ;
}

IPEndPoint localIpEndPoint =
new IPEndPoint(localHostEntry.AddressList[0], UdpPort);

soUdp.Bind(localIpEndPoint);

while (true)
{
Byte[] received = new Byte[1500];

IPEndPoint tmpIpEndPoint =
new IPEndPoint(localHostEntry.AddressList[0], UdpPort);
EndPoint remoteEP = (tmpIpEndPoint);
int bytesReceived = soUdp.ReceiveFrom(received, ref remoteEP);

String dataReceived = System.Text.Encoding.ASCII.GetString(received);
Console.WriteLine(dataReceived.Substring(i, j-i));
}
}
catch (SocketException se)
{
Console.WriteLine("Socket Exception:\n" + se.ToString());
}
}
 
Hi,

mBird said:
Hi --

Thanks for the info --

I tried using the SetSocketOption. To test it I did:
-Created a test listener
-Launched the testlistener.exe twice (so now two apps listening).

Both launched OK (so no longer get errror message "Only one usage of each
socket address (protocol/network address/port) is normally permitted")

But only one app instance sees UDP messages (they are simple console apps
and one sees and prints my UPD messages while the other apps instance just
sits there and does nothing)???

This would indicate that the message is a unicast send. Are you sure that
the trap messages are broadcasted, I don't know much about snmp, after some
reading it seems most snmp agents let you specify a list of host addresses
to send the traps to. This is not the same as broadcasting.

Broadcast messages are send to addresses like 192.168.0.255,
255.255.255.255. Message sent to these addresses can be received by
multiple applications on the same system using SO_REUSEADDR.
The same is true for multicasted messages send to addressses starting with
224 through 239.

If however the messages are sent to a host like 192.168.0.1, then indeed
there is no easy way to make two applications receive them both. If that's
the case then go with Micheal's answer.

HTH,
greetings
Here is the code for a test client I used -- any ideas greatly appretiated!
Thanks

public void StartReceiveFrom()
{
IPHostEntry localHostEntry;

try
{
Socket soUdp =
new Socket(AddressFamily.InterNetwork, SocketType.Dgram,
ProtocolType.Udp);
soUdp.SetSocketOption(SocketOptionLevel.Socket,
SocketOptionName.ReuseAddress, 1);

try
{
localHostEntry = Dns.GetHostByName(Dns.GetHostName());
}
catch(Exception)
{
Console.WriteLine("Local Host not found");
return ;
}

IPEndPoint localIpEndPoint =
new IPEndPoint(localHostEntry.AddressList[0], UdpPort);

soUdp.Bind(localIpEndPoint);

while (true)
{
Byte[] received = new Byte[1500];

IPEndPoint tmpIpEndPoint =
new IPEndPoint(localHostEntry.AddressList[0], UdpPort);
EndPoint remoteEP = (tmpIpEndPoint);
int bytesReceived = soUdp.ReceiveFrom(received, ref remoteEP);

String dataReceived = System.Text.Encoding.ASCII.GetString(received);
Console.WriteLine(dataReceived.Substring(i, j-i));
}
}
catch (SocketException se)
{
Console.WriteLine("Socket Exception:\n" + se.ToString());
}
}


BMermuys said:
Hi,



Some explenation.

You must always bind before you can receive. For connection-oriented
sockets (TCP) this might be done implicitly by a connect call or explicitly
by calling bind before calling listen.

For connection-less oriented sockets (UDP):
To receive unicast udp, you bind to a local addr/port to which udp packets
are sent.

To receive multicast udp, eg sent to 239.255.255.250:1900, you add the ip
address as a multicast group(socketoptions) and then bind to the local port
1900.

Bind allows only one process to bind to one local addr/port pair.

This is ussally fine, but multicast means for everyone, so it makes sense
that multiple processes (aplications) can receive them. SO_REUSEADDR makes
this possible. It allows multiple processes to receive the same broadcast
packet.

Note that even when using the SO_REUSEADDR option unicast udp packets will
only be received by one socket. This because unicast means only one.
Usually the last bounded socket receives it.

Now to set the socket option SO_REUSEADDR in c# call:

Socket _socket;
...
_socket.SetSocketOption(SocketOptionLevel.Socket,
SocketOptionName.ReuseAddress, 1);
...

1 only indicates true.

When you set this option, you indicate that another process may bind to the
same local addr/port.


HTH,
Greetings
 
Hi --
This would indicate that the message is a unicast send.
....

That did it! I just changed my firewall to broadcast to 192.168.1.255
instead of just to my PC (192.168.1.100) and it works great! This is just my
home firewall so no problem broadcasting to the entire LAN at x.x.x.255

Thanks for the great help you gave -- it is appretiated.
 
Thanks for the info.
I got the issue of multiple apps figured out from help from BMermuy's post
(12/9/03) but I also like your idea and I was wondering what the best way to
send a message would be. I can think of two ways:
1.) rebroadcast the incoming UDP message on a different port and have my
other app lust listen for it there
2.) use Remoting
Is there a way to send message beside those and if so please recommend best
way.
Thank you fopr you help!
 
Back
Top