Version 38 of TclUDP

Updated 2005-05-02 06:01:41

The TclUDP package provides Tcl with UDP sockets on Windows and un*x.

The created sockets support the fileevent command and also support multicasting and binary data. The package has recently been restructured as a TEA2 compliant package with build testing done for Linux, Windows and OpenBSD.

TclUDP is now a project at sourceforge [L1 ] ("owned" by Xiataow, but maintained by PT) and the latest releases will be available at [L2 ].

With TclUPD, you first create a socket on the local system:

  set sock [udp_open]

You can also specify a port number if that is required. You could set the characteristics of the socket with

  fconfigure $sock -buffering none -translation binary

You specify the other end-point for the UDP datagram with 'udp_conf':

  udp_conf $sock somserv.example.com $watchPort

You can send datagrams (of up to 4096 bytes) with 'puts' and read incoming datagrams with 'gets'.

  puts $sock "Pack my box with four dozen liquor jugs."

You can also use 'fileevent' to specify a callback that should be invoked when a UDP datagram arrives:

  fileevent $srvsock readable [list ::udpCallback $srvsock]

The following does only indirectly pertain to TclUDP. These are some speculations on what a UDP package for tcl could look like.


[PT] writes on 11Mar03: The current interface to this package isn't quite what we'd like to see for Tcl. I'm currently implementing the bits required to support the stock fconfigure command. For the future I think that I'd like to see a udp command very much like socket. This could then be used as

  set u [udp $remote $port]         ; # create a udp socket and set the target
  set u [udp]                       ; # create a udp client socket that requires configuring later
  set u [udp -server handler $port] ; # create a udp server socket listening on $port

UDP sockets are not normally connected to anyone. So fconfigure can be used to redirect outbound traffic. The server handler can use fconfigure $u -peer to obtain information about who sent the current packet. So the same socket could be used to fire off packets to a list of hosts.

  proc handler {sock} { do stuff }
  set u [udp]
  fconfigure $u -buffering none -translation binary
  fileevent $u readable [list ::handler $u]
  foreach {host port} $targetlist {
     fconfigure $u -remote [list $host $port]
     puts -nonewline $u $data
  }

Note that to read data from a udp socket, you will always have to set up a fileevent handler.

Seems reasonable - until aku invents his Tcl Event System :)


[Jacob Levy] writes on March 11, 2003: This all seems very reasonable. Then a small step forward would be to convert it to using the socket command like this:

  set u [socket -udp $remote $port]         ; # create a udp socket and set the target
  set u [socket -udp]                       ; # this one needs to be fconfigured later
  set u [socket -udp -server handler $port] ; # create a udp server listening on $port

Note that this is backwards compatible with the regular socket command.

Question: in the readable handler, is there any way to find out the name/IP address of who made it readable? Is the read blocking, i.e. will it block if you try to read more than what's there?

[PT] answers: As for the socket command, fconfigure -peername will return the senders details for the current packet. As for blocking - the udp socket cannot be blocking. What happens is that read reads data from a single packet until it's complete. If you try to read too much, an end of data gets returned once the packet is exhausted. So you can safely use set d [read $sock] and be sure to only get the data from one packet. With udp it usually makes sense to have buffering off - so this generally means you read the entire packet.


ECS on 20041122 - The multicast packets are sent with a TTL of 1, so they don't cross routers. Maybe we should add an option to define the TTL?

PT 22-Nov-2004: Which version are you using and on what operating system? It would be useful to me if you provide a small sample that uses multicast. I don't have something that I know works for testing this. However, what I can do is add a fconfigure option that can call get/setsockopt(s, SOL_IP, IP_TTL, &ttl);

If you raise a bug at [L3 ] you can get notified when it's dealt with.

In fact - I'm just checking this in:

 % load libudp1.0.6.so
 % set u [udp_open]
 sock3
 % fconfigure $u -buffering none -blocking 0 -broadcast 1 -remote {172.16.255.255 9876}
 % puts -nonewline $u test
 % fconfigure $u -ttl 10
 % puts -nonewline $u test

The above gives me the following packets using tcpdump:

 09:31:39.665765 IP (tos 0x0, ttl 64, id 0, len 32) host.example.com.1140 > 172.16.255.255.9876: [udp sum ok] udp 4 (DF)
 09:31:39.665765 IP (tos 0x0, ttl 10, id 0, len 32) host.example.com.1140 > 172.16.255.255.9876: [udp sum ok] udp 4 (DF)

ECS 20041122 - Well, I am using tcl 8.4.7, TclUDP (1.0.5) available on sourceforge, and running on linux (2.4.27-ow1). The problem seems to be related with multicast. Look the code below: [snip] Maybe I just misunderstood the documentation. BTW

PT - No - you haven't misread the docs. I'm working on this NOW so what I'm showing above the the current CVS head version. I've implemented a -ttl. This affects normal UDP. For multicast UDP, it seems we have to use IP_MULTICAST_TTL. So I'm arranging this such that if the socket has multicast groups added, then I'll also set the multicast ttl. You will need to checkout the CVS source to try this -

 cvs -d:pserver:[email protected]:/cvsroot/tcludp co tcludp (changed from udp UK)

However, the anonymous access may lag behind ssh access by some time - usually only a few hours I understand.

ECS - Thanks, I will check in a few hours. I did changed udp_tcl.c to set TTL just after join the multicast group. I used 31 (site multicast) but I think it will be better to have the value as an option in udp_conf or fconfigure, as you wish. This way we can limit packet propagation.

PT - It is in now - the revision version for the new version of udp_tcl.c is 1.17. I intend to depreciate [udp_conf] in favour of [fconfigure] but both commands are supported. To set the multicast ttl you should have first set a multicast group.

 fconfigure $udpsock -mcastadd 224.5.1.21 -ttl 31

will work. I have also made the channel remember the mcast groups added and it now calls the mcastdrop code for each one still in the list when the channel is closed. This seems like a good idea - but do you agree?


Is TclUDP stubsified? This [L4 ] suggests it is.

PT - Just to be explicit -- tcludp links against tclstubs but doesn't provide its own stubs library. If this is required I can do that.

Pat, my current interest is in construction of Starpacks that embed TclUDP. Can do?


CL had written misinformation about Mac here. Daniel correctly concludes:

DAS: note that TclUDP is part of my Mac OS X TclTkAquaBI distro already, a small patch [L5 ] is required to build properly on Mac OS X.


"... on Windows you need to close the channels before issuing an exit--seems to get hung up in event wait otherwise."

Jeff Smith 2 May 2005 -- I noticed in the changelog that a fix had been applied for this issue and the version bumped to 1.07. Will there be a "udp107-win32.zip" file available for download in the near future? :)


[ Category Internet | Category Package ]