The TclUDP package provides [Tcl] with [UDP] [socket]s 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 [TEA3] compliant package with build testing done for [Linux], Windows, Solaris and [OpenBSD]. TclUDP is now a project at sourceforge [http://sourceforge.net/projects/tcludp] ("owned" by Xiataow, but maintained by [PT]) and the latest releases will be available at [http://prdownloads.sourceforge.net/tcludp/]. The latest version is 1.0.8. [[[ysk]]] Question: 1.0.9 is available in teapot. What's the difference? **Usage** First, bring the TclUDP package into your Tcl interpreter with ====== package require udp ====== Then, 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 'fconfigure' (in old versions 'udp_conf'): ====== fconfigure $sock -remote [list $serverName $servicePort] ##deprecated## udp_conf $sock $serverName $servicePort ====== You can send datagrams (of up to 4096 bytes) with 'puts' and read incoming datagrams with 'gets'. Do not forget to configure the translation mode of the socket for your needs. ====== puts -nonewline $sock "Pack my box with four dozen liquor jugs." ====== You should use [fileevent] to specify a callback that should be invoked when a UDP datagram arrives: ====== proc OnUdpDataReceived {channel} { set packet [read $channel] set peer [fconfigure $channel -peer] # Do something with the data and/or the peer address information return } fileevent $sock readable [list OnUdpDataReceived $sock] ====== See the ''demos/'' folder in the source distribution for a number of examples including the use of multicast and broadcast UDP sample programs. ---- **Future directions** The following does only indirectly pertain to TclUDP. These are some speculations on what a UDP package for tcl '''could''' look like. [PT] There is some work on a version 2 udp package which will drop the udp_open and udp_conf commands in favour of a single [[udp]] command for creating the channel instance and then use the [[fconfigure]] command for everything else. As of udp 1.0.6 the fconfigure functionality is already in place. The [[udp]] command will permit specification of the local interface with a ''-myaddr'' option and also supports a ''-reuseaddr'' flag to set the SO_REUSEADDR socket option so that multiple sockets can bind an address. I also want to sort out the IPv6 side of things so that the same library can handle both ipv4 and ipv6 connections. ---- [[[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. ---- Pat has written, "Multicast is a little different to standard unicast or broadcast UDP. Your operating system ignores multicast packets unless an application has explicitly joined a multicast group. In the case of TclUDP we do this by using ====== fconfigure $socket -mcastadd $mcastaddress ====== This actually results in a system call that causes the system to start listening to packets addresses to this group. In C this would be: ======c setsockopt(socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, ....); ====== Once the system is no longer ignoring such packets, normal UDP addressing takes effect. This means that you need to send to this multicast address and in order to receive packets you need to have a listening socket open and bound to the correct address and port. It is not necessary to join the multicast group to send but it is necessary if you want to receive. There is a minimal demo called '''multicast.tcl''' in the tcludp '''demos/''' folder (as distributed in the source package). If you run that as tclsh multicast.tcl it listens to group 224.5.1.21 port 7771. You can send to it using '''netcat''' (or the '''chat.tcl''' demo) eg: echo "testing " | nc -u 224.5.1.21 7771 or using bash echo "testing " >/dev/udp/224.5.1.21/7771 or wish demos/chat.tcl " ---- TclUDP is [stubs]-enabled to the extent of not being bound to a specific version of Tcl. Unlike, say, [memchan], it does ''not'' '''provide''' stubs (nor should it ...). [RLE] (2014-01-09): Quoting above: : "You can send datagrams (of up to 4096 bytes) with 'puts'" Is there a reason for the 4,096 byte limitation. The maximum ipv4 UDP packet is 65,507 bytes [http://en.wikipedia.org/wiki/User_Datagram_Protocol#Packet_structure] so why limit to 4,096 in the extension? <> Package | Internet | Networking | Channel