Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

UDP socket: working with multiple network interface

2,143 views
Skip to first unread message

TM

unread,
Dec 6, 2012, 8:30:27 AM12/6/12
to
Hi,

In a computer with multiple network interfaces, how can I select which NIC to use when opening a UDP socket?

(There is an old thread on the subject from 2007 that basically reads that I can't do it; I'm hoping someone can provide an update with good news)

I have written an application that relies on the "Tcl UDP extension" to establish comms between a PC and an instrument. The instrument has a fixed IP address in a private network (typically 192.168.***.***).

At the moment, I manually fix the IP address of the PC to be in the same private network of the instrument, then start the TCL application and talk to the instrument with:

if {[catch {udp_open $port} channel]} {...}

The snag is that I have no intranet not internet access when I am talking to the instrument.

I would like to add a 2nd NIC to the PC so that I can have the extra networking whilst simultaneously talking to the instrument. Any ideas how this could be done in TCL?

Thanks
TM

Uwe Klein

unread,
Dec 6, 2012, 9:17:58 AM12/6/12
to
If you have one interface with an IP from 192.168.0.0/16
and one with another IP on a different net
you should get internal routing to the right interface
if you send to your appliance in the 192.168.0.0/16 net
( only issue I ever had was with multicast adresses
which interfaces get multicast routing !? )

uwe

TM

unread,
Dec 6, 2012, 10:22:59 AM12/6/12
to
Hi Uwe,

I'm opening a port for reading.

I cannot set the NIC with 'udp_open'. So, how can I be sure that I am only listening to data arriving from a specific NIC? How does the OS know which NIC I want to get data from?

Or is TCL listening to the specified port on **all** NIC?

I use the following code to get the UDP comms going:

# open socket
if {[catch {udp_open $port} channel]} {return -code error $channel}

# configure channel
fconfigure $channel \
-buffering none -blocking 0 \
-encoding binary -translation binary

# and start listening
fileevent $channel readable [list PacketServer $channel]

vwait running

Thanks
TM

Uwe Klein

unread,
Dec 6, 2012, 10:58:42 AM12/6/12
to
TM wrote:
> Hi Uwe,
>
> I'm opening a port for reading.
>
> I cannot set the NIC with 'udp_open'. So, how can I be sure that I am only listening to data arriving from a specific NIC? How does the OS know which NIC I want to get data from?
>
> Or is TCL listening to the specified port on **all** NIC?

yes, that is the default config.
You will see all datagrams to the port you are listening on on all interfaces.

>
> I use the following code to get the UDP comms going:
>
> # open socket
> if {[catch {udp_open $port} channel]} {return -code error $channel}
>
> # configure channel
> fconfigure $channel \
> -buffering none -blocking 0 \
> -encoding binary -translation binary
>
> # and start listening
> fileevent $channel readable [list PacketServer $channel]
>
> vwait running

Looks like that should work.

apropos: what OS/system are you using?

uwe

hae

unread,
Dec 7, 2012, 1:57:16 AM12/7/12
to
Hi TM,

for Windows XP and IPv4 you can't bind to a specific nic.
For Details see:

http://stackoverflow.com/questions/2065495/using-a-specific-network-interface-for-a-socket-in-windows

Ruediger

TM

unread,
Dec 7, 2012, 5:13:23 AM12/7/12
to
Uwe, Ruediger,

Thanks for the feedback.

I'm using XP for development but the script needs to also run on Windows 7 + Linux. I'll add OS-specific variants if I must, but I really want to just write a common TCL script that just runs in all platforms!

From what you said - TCL binds the selected reading port to all NICs - it looks like I should be able to manage my application. To avoid receiving odd packets from the 2nd NIC (say, connected to the internet), I can use a combination of:

- Select an uncommon port (tricky on its own, since you never know what ports new software is going to start using)

- Add a application-specific field to the header in each UDP packet.

TM

hae

unread,
Dec 7, 2012, 6:02:25 AM12/7/12
to
Hi TM,

when you receive a UDP packet you can check the IP-address of the sender with

set SenderIP [fconfigure $channel -peer]

However I don't know if this is performant.

Ruediger

TM

unread,
Dec 7, 2012, 7:03:32 AM12/7/12
to
Hi Ruediger

Yes, that is the proper way to do it. I have to test it to see if it gives me the performance I need without loosing packets.

I don't really like the idea of having to add a field to the UDP packet to ensure I am only parsing packets from the NIC connected to my instrument. This solution is not bomb-proof: there is always going to be a chance that some packet from the 2nd NIC supplies a matching field...

The fall-back plan is to do what I have done so far: to enforce that the PC only has 1 NIC connected to the instrument.

TM

Les Cargill

unread,
Dec 7, 2012, 8:46:11 AM12/7/12
to
Perhaps I am confused, but... traffic between you and this instrument
should be multiplexed by UDP port number. This selection mechanism
should already be in place. In addition, you'll have vanishingly
little UDP traffic on the intranet/internet.

Your app can also use the UDP extension to obtain the hostname and
port number of the sender of packets received. It's something
like the -peer option on the udp_conf command.

And there may be a way to assign a NIC only to a VM.

--
Les Cargill

Donal K. Fellows

unread,
Dec 7, 2012, 9:29:06 AM12/7/12
to
Can you get the local address of the receiving socket for that packet?
If so, that will tell you which NIC it was received on (unless someone's
configured them to pretend to have the same address, in which case
you're not *supposed* to tell them apart in the first place) and it is
information that always exists (it's part of the IP layer of UDP/IP and
TCP/IP; it really should be present).

Donal.

0 new messages