I'm starting to learn tcl script language, and I was trying to do a tcl script that tunnels all the multicast packets across a unicast network.
Since I'm newcomer concerning to tcl, I would like to ask to points:
I'm using Eclipse to code in tcl, I have installed the needed plug-in and I think also all the packages, however, Eclipse underlines me the following call
fconfigure $sockMulticast -buffering none -mcastadd $ipMulticast -translation binary -remote [list $ipMulticast $port]
Saying that there is extra arguments, which I don't understand since here it can be read:
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
When I configure the TCP socket, the unicast one, should I specify again the destination unicast IP again when invoking
fconfigure
?
Code:
#!/bin/sh
# updToTcp.tcl \
exec tclsh "$0" ${1+"$@"}
package require udp
set ::connectionsMulticast [list]
set ::connectionsUnicast [list]
proc udp_connect {ipMulticast ipUnicast port {multicast false}} {
#Open UDP multicast socket
set sockMulticast [udp_open $port]
if {$multicast} {
#configures the multicast port
fconfigure $sockMulticast -buffering none -mcastadd $ipMulticast -translation binary -remote [list $ipMulticast $port] ;#(1)
#update the list of multicast connections with the socket
lappend ::connectionsMulticast[list $ipMulticast $port $socketMulticast]
#Open TCP unicast socket
set sockUnicast [socket $ipUnicast $port]
#configures the unicast port
fconfigure $sockUnicast -buffering none -translation binary;#(2)
#update the list of unicast connections with the socket
lappend ::connectionsMulticast[list $ipUnicast $port $socketUnicast]
#listen to the multicast socket, and forwarding the data to the unicast one
fileevent $sockMulticast readable [list ::dataForwarding $sockMulticast $sockUnicast]
}
}
proc dataForwarding {socketSrc socketDst} {
#get the data from the source socket, and place it on data
set data [read $socketSrc]
#placing the data in the destination socket
puts -nonewline $socketDst $data
return
}
On the first point, Eclipse is plain wrong. The
fconfigure
command can take any number of option/value pairs (or a single option to retrieve a value, or no options to retrieve many values at once — though not necessarily all; serial channels have some odd features, but they don't matter to you at the moment). It's unfortunate that they're wrong, but it happens.On the second point, I would not try to change the IP address of a TCP endpoint; you can't do that (strictly, not with Tcl's binding; I've no idea at all if you can do so in general). TCP and UDP channels have very different restrictions on what can be changed and when (because TCP channels use a handshake protocol to build a connected session between two ports, whereas UDP has no such restriction at all; in return, TCP channels can be regarded as reliable streams, whereas UDP is not a streaming protocol at all and has no sessions/connections).
You also have a problem with your
lappend
calls; you're omitting a crucial space between the variable name and the value to append to those global lists. This will mean that the global variables that you expect to hold the lists of connection information will not actually be doing so; instead you'll get lots of strange variables with wholly impractical names. And it will all totally break if you add IPv6 support (as that can use::
in the rendering of IP addresses, despite it also being a Tcl namespace separator). Fix it now; save yourself a bit of trouble in the future...