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]). | |
| 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 | ( | ) |
(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")))))
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!!
(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)
...))
(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.
(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
(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.
(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] |
muse_port_type_t g_multicast_socket_type [static] |
Initial value:
{
{
'muSE',
'port',
sizeof(multicast_socket_port_t),
NULL,
NULL,
multicast_socket_init,
NULL,
multicast_socket_destroy,
NULL
},
multicast_socket_close,
multicast_socket_read,
multicast_socket_write,
multicast_socket_flush
}
1.4.7