AT&T Home | AT&T Labs | Research
AT&T Labs, Inc. - Research

The Yoix® Scripting Language

Home | What's New | Grammar | Documentation | Download | License | YChart | YDAT | YWAIT | Byzgraf | FAQs
MulticastSocket typedict
 
A MulticastSocket is the Yoix representation of Java's MulticastSocket class that can be used to join multicast groups and to send and receive multicast UDP (User Datagram Protocol) packets.

We have had mixed results using MulticastSockets and have not had time to really track the problems down. The Linux systems that we used for testing behaved poorly, while OSX and Windows did much better. The problems that we encountered could be mistakes in our Java code, however some long-standing bugs summarized in the 4701650 Java bug report seem to describe our experience. We plan on more testing and debugging, but until then you probably should suspect low level Java or Yoix interpreter bugs if you have trouble using MulticastSockets, particularly on Linux systems.

The fields in a MulticastSocket are:
alive An int that is 1 if the multicastsocket has been activated and 0 otherwise. Storing 1 in alive activates the multicastsocket, which automatically tries to bind it to localaddress and localport and then connect it to remoteaddress and remoteport. Calling the send or receive built-ins also activate the multicastsocket. Storing 0 in alive closes the multicastsocket, which means it is no longer bound to a local address or connected to a remote system.
broadcast An int that is 1 if the multicastsocket can send broadcast datagrams and 0 if it can not. Storing a negative number in broadcast is ignored and makes no changes to the current setting.
joinGroup(String address) A Builtin that tries to join the multicast group address, which should be a IP address in the range 224.0.0.0 to 239.255.255.255 or a name that can be resolved by DNS to an IP address in that range, and returns 1 if the group was successfully joined and 0 if it was not. Groups that we successfully join are also added to the joinedgroups array.

Addresses 224.0.0.0 through 224.0.0.255 are reserved for local administrative purposes. For example, ping 224.0.0.1, which is the group that every multicast capable host joins when it starts up, and all hosts in that group should answer. Addresses 239.0.0.0 through 239.255.255.255 are reserved for administrative scoping.

joinedgroups An Array that lists the multicast groups that this mulitcastsocket currently belongs to, or NULL if the list of groups is empty.
leaveGroup(String address) A Builtin that tries to leave the multicast group address, which should be a IP address in the range 224.0.0.0 to 239.255.255.255 or a name that can be resolved by DNS to an IP address in that range, and returns 1 if the group was successfully left and 0 if it was not. Groups that we successfully leave are removed from the joinedgroups array.
localaddress A String that identifies network interfaces on the local machine that the multicastsocket will bind to when it is activated. localaddress is currently a read-only field, which means the multicastsocket always binds to the wildcard address that usually matches any local address. Changing localaddress is not allowed and will result in an invalidaccess error. This was done in response to Java bug report 4701650, which states that binding to a specific address can result in "wildly platform specific behavior".
localname A read-only String that is the name of the host associated with the IP address read from localaddress when the multicastsocket is alive and NULL when it is not alive.
localport An int that identifies the port that the multicastsocket will bind to when it is activated. The value should be an integer between 0 (the default) and 65535, inclusive. A localport that is 0 means the system should pick an ephemeral port. A multicastsocket that is bound to localaddress and localport will only receive packets directed to that address and port. Changing localport while a multicastsocket is alive is not allowed and will result in an invalidaccess error.
loopback An int that is 1 (the default) if packets sent by this multicastsocket to a group that it joined should be looped back for local delivery to this multicastsocket, and 0 if they should not. In other words, setting loopbackmode to 0 means this multicastsocket does not want to receive the data that it sends a multicast group. Storing a negative number in loopbackmode is ignored and makes no changes to the current setting.

Some of the simple tests that we ran on Windows and OSX seemed to misbehave when 0 was stored in loopbackmode, which is why the default mode is enabled.

networkinterface A String that should be the name of the network interface (e.g., eth0 or lo), that should be used for multicast packets that are sent by this multicastsocket.
receive(String buf [, Pointer addr, Pointer port]) A Builtin that waits for a datagram packet to arrive at this multicastsocket's localaddress and localport, stores the packet data in buf, and returns the number of bytes received or -1 if receive timed out, was interrupted, or encountered any other kind of error. receive automatically activates the multicastsocket if it is not alive.

The string buffer buf must be large enough to accommodate the data in any expected packet; bytes that don't fit will be lost. Information about where the data came from can stored in the locations that the optional addr and port arguments point to. addr should point to a string that will be filled in with the IP address of the host that sent the data. port should point to an integer that will be filled in with a port that can be used to contact the host that sent the data. A multicastsocket that is connected to remoteaddress and remoteport can only receive packets from that address and port, which means the optional addr and port arguments will not provide any additional information.

receivebuffersize An int that is the size, in bytes, of the buffer used by the multicastsocket to receive packets. Reading returns the actual buffer size if the multicastsocket is alive, or the size that will be requested from the operating system when it is activated. Writing requests a buffer of a certain size, however the request may or may not be honored by the operating system. Storing a negative number in receivebuffersize is ignored and makes no changes to the current setting.
remoteaddress A String that identifies a remote system that the multicastsocket should be connected to when it is alive. The value should be an IP address, a name that can be resolved by DNS, or NULL (the default) which means the multicastsocket is not connected. A multicastsocket that is alive and connected to remoteaddress and remoteport can only send packets to or receive packets from that address and port. A multicastsocket that is alive and has a NULL remoteaddress or a remoteport that is -1 is not connected to a remote system. Reading remoteaddress when the multicastsocket is alive always returns the IP address or NULL. Writing first disconnects the multicastsocket and then tries to establish a new connection when remoteaddress is not NULL and remoteport is integer between 0 and 65535, inclusive.
remotename A read-only String that is the name of the host associated with the IP address read from remoteaddress or NULL when the multicastsocket is not alive or not connected to a remote system.
remoteport An int that identifies the port on remoteaddress that the multicastsocket should be connected to when it is alive. A multicastsocket that is alive and connected to remoteaddress and remoteport can only send packets to or receive packets from that address and port. A multicastsocket that is alive and has a NULL remoteaddress or a remoteport that is -1 is not connected to a remote system. Writing first disconnects the multicastsocket and then tries to establish a new connection when remoteport is integer between 0 and 65535, inclusive and remoteaddress is not NULL.
reuseaddress An int that is 1 if more than one multicastsocket can be bound to the same localaddress and localport pair and 0 otherwise. Storing a negative number in reuseaddress is ignored and makes no changes to the current setting.
send(String buf [, String addr, int port]) A Builtin that uses this multicastsocket to send the contents of buf to a remote system and returns the number of bytes sent or -1 if there was an error. Nothing is sent and 0 is returned if buf is NULL or the empty string (i.e., ""). send automatically activates the multicastsocket if it is not alive.

A multicastsocket that is connected to remoteaddress and remoteport can only send packets to that address and port, which means the optional addr and port arguments should be omitted. A multicastsocket that is not connected to a remote system must be told where buf should go using the addr and port arguments. addr should be an IP address, a name that can be resolved by DNS, or NULL which is a convenient way to refer to the local host. port should be an integer between 0 to 65535, inclusive.

sendbuffersize An int that is the size, in bytes, of the network buffers used by the multicastsocket to send packets. Reading returns the actual size if the multicastsocket is alive, or the size that will be requested from the operating system when it is activated. Writing requests buffers of a certain size, however the request may or may not be honored by the operating system. Storing a negative number in sendbuffersize is ignored and makes no changes to the current setting.
timeout A double that specifies how long the receive built-in will wait, in seconds, before giving up. A zero value disables timeouts and means receive will wait forever. Writing is allowed, but does not affect a receive call that has already started. Storing a negative number in timeout is ignored and makes no changes to the current setting.
timetolive An int between 0 and 255 that is used as the time-to-live for multicast packets that are sent by this multicastsocket. When a packet passes through a router its time-to-live is decremented and when it gets to 0 it will not be transmitted. Setting timetolive to 1 means multicast packets will only be transmitted on the local network. A value greater that 1 means mulitcast packets may be forwarded to other networks, while 0 means multicast packets will not be transmitted on any network. Storing a negative number in timetolive is ignored and makes no changes to the current setting.
trafficclass An int that requests a type-of-service and precedence, using constants defined in yoix.net, for datagrams that are sent from the multicastsocket. The type-of-service should be one of IPTOS_LOWCOST, IPTOS_LOWDELAY, IPTOS_RELIABILITY, IPTOS_THROUGHPUT, or IPTOS_NORMAL (the default), while the precedence should be one of IPPREC_0 (the default), IPPREC_1, IPPREC_2, IPPREC_3, IPPREC_4, IPPREC_5, IPPREC_6, or IPPREC_7. The type-of-service and precedence can be combined using a bitwise-or operation and the result can be stored in trafficclass. Storing a negative number in trafficclass is ignored and makes no changes to the current setting.

Two other constants defined in yoix.net, namely IPTOS_MASK and IPPREC_MASK, can be used to extract the type-of-service and precedence from the value obtained when the trafficclass field is read.

Several permanent fields have not been documented and should not be used in Yoix applications. If you look closely you may notice that many fields in a MulticastSocket are initialized with values, like -1, that the documentation says are explicitly ignored. It is an approach that lets Java (and your operating system) pick values when the multicastsocket is activated for fields that you choose not to initialize.
 
 Example:   The program
import yoix.*.*;

MulticastSocket socket;
String          buf[100];
String          address;
String          name;
String          message;
String          group;
int             counter = 1;
int             port;
int             count;
int             n;

if (argc == 2 || argc == 3) {
    if (isMulticastAddress(argv[1])) {
        socket.localport = 6789;
        socket.joinGroup(argv[1]);
        name = (argc == 3) ? argv[2] : "unknown";
    } else fprintf(stderr, "invalid address\n", argv[1]);
} else fprintf(stderr, "usage error\n");

if (socket.joinedgroups != NULL) {
    socket.timeout = 1;
    socket.timetolive = 1;
    group = socket.joinedgroups[0];
    for (n = 0; n < 20; n++) {
        message = strfmt("message %d from %s", counter++, name);
        count = socket.send(message, group, socket.localport);
        printf("    sent: count=%d bytes to %s:%d\n",
            count, group, socket.localport);
        sleep(2);
        while (socket.receive(buf, &address, &port) > 0)
            printf("received: %s from %s:%d\n", buf, address, port);
        sleep(2);
    }
}
is a simple MulitcastSocket test that currently only sends packets out on your local network (because timetolive is set to 1). Type something like,
yoix multicasttest.yx 228.5.6.7 john
to start sending messages to multicast group 228.5.6.7 as "john",
yoix multicasttest.yx 228.5.6.7 rich
to start sending messages to the same group as "rich", and both should start receiving all the messages that are sent to the group. Unfortunately we have had some problems with MulitcastSockets, particularly on Linux, so you may not have much luck running this script.
 
 See Also:   DatagramSocket, getAddress, getAllByName, getHostAddress, getHostName, getInterfaceAddress, getInterfaceAddresses, isAnyLocalAddress, isLinkLocalAddress, isLoopbackAddress, isMulticastAddress, isSiteLocalAddress, ServerSocket, Socket

 

Yoix is a registered trademark of AT&T Inc.