Networking


Point to point communication

Made possible through the functions

muse_cell fn_with_connection_to_server (muse_env *env, void *context, muse_cell args)
 (with-connection-to-server server-port-string service-fn).
muse_cell fn_with_incoming_connections_to_port (muse_env *env, void *context, muse_cell args)
 (with-incoming-connections-to-port port-number service-fn).

Multicast messaging

A simple multicast mechanism is implemented using UDP datagrams. You join a multicast group by creating a muSE port using the function multicast-group. Once the join succeeds, you can broadcast a message to the group and can receive broadcast messages from any member of the group using the standard read and write functions.

Immediately after a read, information about the sender is stored internally and you can reply to the sender alone by using the reply function. reply works only with multicast group ports. It is a programming error to use it with other ports.

You can use the wait-for-input function to wait for a message from a multicast group as well.

muse_cell fn_multicast_group (muse_env *env, void *context, muse_cell args)
 (multicast-group [address] [port]).
muse_cell fn_reply (muse_env *env, void *context, muse_cell args)
 (reply port).
muse_cell fn_multicast_group_p (muse_env *env, void *context, muse_cell args)
 (multicast-group? p).
static void multicast_socket_init (void *p, muse_cell args)
static void multicast_socket_close (void *p)
static void multicast_socket_destroy (void *p)
static size_t multicast_socket_read (void *buffer, size_t nbytes, void *p)
static size_t multicast_socket_write (void *buffer, size_t nbytes, void *p)
static int multicast_socket_flush (void *p)
static muse_port_type_t g_multicast_socket_type

Functions

muse_boolean muse_network_startup ()
 In the POSIX version, we initially setup to block the SIGPIPE signal.
void muse_network_shutdown ()
muse_cell fn_wait_for_input (muse_env *env, void *context, muse_cell args)
 (wait-for-input network-port [timeout-microseconds]).

Function Documentation

muse_boolean muse_network_startup (  ) 

In the POSIX version, we initially setup to block the SIGPIPE signal.

The SIGPIPE signal will be sent if we try to write into a socket whose read end has closed. This behaviour, when not masked out, causes the server to exit, and we don't want that to happen.

send() should then return EPIPE, which will be transformed into an IOException class.

More info can be found at - Unix-socket-faq Unix programming FAQ

void muse_network_shutdown (  ) 

muse_cell fn_with_connection_to_server ( muse_env env,
void *  context,
muse_cell  args 
)

(with-connection-to-server server-port-string service-fn).

Connects to the given server on the given port and invokes the given service-fn with the reader and writer for the connection. Works only with s-expression streams.

For example -

 (with-connection-to-server "123.234.134.23:8080"
     (fn (port)
        (write port '(hello world))
        (case (read port)
           ('hi (print "Success!\n"))
           (()  (print "Failed!\n")))))

See also:
fn_with_incoming_connections_to_port()

NOTE:

Windows doesn't close blocking sockets properly if you ask it to do a "graceful close". This affects the other side of the network. For example, Java doesn't get to throw an IOException upon a sincere plain closesocket() call and just hangs on the InputStream's read() method. The painful part is that this behaviour is not consistent from socket to socket. For one socket the close operation might succeed gracefully whereas for another it might fail, for no particular fault of yours.

Therefore the default way we'll close client sockets in Windows is by setting it to do a "hard close".

To do such a "hard close", you set the SO_LINGER parameter of the socket and give a zero timeout period. This is what the following setsockopt() call does.

CORRECTION: Sorry! It doesn't seem to be a Windows problem.It is supposed to be standard socket behaviour. The closesocket() call will ultimately result in the local socket being close only after the remote socket closes. How does the remote socket know when to close? He should check the return value of the read() call. When read() returns 0, it is supposed to indicate closing time (other possibility is a shutdown()). But Java doesn't return from read at all!!

muse_cell fn_with_incoming_connections_to_port ( muse_env env,
void *  context,
muse_cell  args 
)

(with-incoming-connections-to-port port-number service-fn).

Listens for connections to the given port and invokes the service function with the connection information..

 (with-incoming-connections-to-port 1234
   (fn (port client-info)
      ...))
If the service function returns (), the server is terminated, otherwise the server will accept the next connection and service it.

See also:
fn_with_connection_to_server()

muse_cell fn_wait_for_input ( muse_env env,
void *  context,
muse_cell  args 
)

(wait-for-input network-port [timeout-microseconds]).

Returns T if input is available and 'timeout if the wait timed out. Returns () upon error. Works only for network ports. It won't wait for file-based ports.

muse_cell fn_multicast_group ( muse_env env,
void *  context,
muse_cell  args 
)

(multicast-group [address] [port]).

Creates a port that represents a multicast group. You can send messages to the group by writing to the port and you can receive messages to the group by reading from the port. Loopback is disabled, so you won't receive your own messages. If you don't specify the port, the port 31415 is used. If you don't specify the address as well, the group address "231.41.59.26" is used.

Note that you should use relatively small expressions. The safest expressions are those that fit within about 512 bytes. If you use multicast-groups like you use SMS, you'll be fine. If you give too large a message, then the write will fail and return () and no message will be sent. You can check for the condition, therefore, at runtime.

You should only use multicast group addresses in the range - 225.0.0.0 to 231.255.255.255. For details, see http://www.iana.org/assignments/multicast-addresses

muse_cell fn_reply ( muse_env env,
void *  context,
muse_cell  args 
)

(reply port).

Immediately after a multicast read succeeds, you have the chance to reply specifically to that client. This is possible because the sender's information is stored in the multicast port structure.

< We support only multicast sockets.

muse_cell fn_multicast_group_p ( muse_env env,
void *  context,
muse_cell  args 
)

(multicast-group? p).

Returns p if it is a multicast port and MUSE_NIL if it isn't.

static void multicast_socket_init ( void *  p,
muse_cell  args 
) [static]

static void multicast_socket_close ( void *  p  )  [static]

static void multicast_socket_destroy ( void *  p  )  [static]

static size_t multicast_socket_read ( void *  buffer,
size_t  nbytes,
void *  p 
) [static]

static size_t multicast_socket_write ( void *  buffer,
size_t  nbytes,
void *  p 
) [static]

static int multicast_socket_flush ( void *  p  )  [static]


Variable Documentation

muse_port_type_t g_multicast_socket_type [static]

Initial value:


Generated on Mon Sep 25 23:12:50 2006 for muSE by  doxygen 1.4.7