Changes between Version 12 and Version 13 of DatagramChannelsCowan


Ignore:
Timestamp:
10/30/13 14:42:41 (4 years ago)
Author:
cowan
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • DatagramChannelsCowan

    v12 v13  
    33Datagram channels are a mild abstraction of UDP sockets.  They are a disjoint type. 
    44 
    5 In the following descriptions, ''host'' and ''local-address'' are strings, which may be IPv4 dotted-decimal addresses, IPv6 colon-hexadecimal addresses if supported by the operating system, or host names to be looked up according to whatever operating system conventions exist, if any.   They can also be specified as bytevectors of length 4 or 16.  Appropriate values may refer to broadcast or multicast addresses. 
    6  
    7 ''Port'' may be an integer or a string; the meaning of a string is implementation-dependent, but is intended to be a standardized service name. 
     5See NetworkEndpointsCowan for network endpoints, an abstraction of a host or address plus a port number.  Several of the following procedures accept or return endpoints. 
    86 
    97== Procedures == 
    108 
    11 `(make-datagram-channel `[''local-address'']` `[''port'']`)` 
     9`(make-datagram-channel `[''endpoint'']`)` 
    1210 
    13 Returns a new datagram channel suitable for sending and receiving datagrams.  If ''port'' is omitted, the channel will receive datagrams that are sent to a unused port assigned by the operating system over any local address.  If ''port'' is present but ''local-address'' is omitted or has the value `#t`, the channel will receive datagrams that are sent to ''port'' over any local address.  Otherwise, the channel will only receive datagrams sent to the specified local address and port.  If there is exactly one argument, it is ''port'', as this is the more common case. In Posix terms this is `socket()` immediately followed by `bind()`. 
     11Returns a new datagram channel suitable for sending and receiving datagrams.  ''Endpoint'' specifies the local endpoint of the channel; if it is omitted, the endpoint will specify any local address and a port specified by the operating system, the equivalent of `(make-network-endpoint #t 0)`. In Posix terms this is `socket()` immediately followed by `bind()`. 
    1412 
    1513`(make-output-only-datagram-channel)` 
    1614 
    17 Returns a new datagram channel only suitable for sending datagrams.  It is not bound to any port.  In Posix terms this is `socket()`. 
     15Returns a newly allocated datagram channel only suitable for sending datagrams.  It is not bound to any port.  In Posix terms this is `socket()`. 
    1816 
    1917`(datagram-channel? `''obj''`)` 
     
    2119Returns `#t` if ''obj'' is a datagram channel and `#f` otherwise. 
    2220 
    23 `(datagram-channel-local-address `''channel''`)` 
     21`(datagram-channel-local-endpoint`''channel''`)` 
    2422 
    25 Returns the local address on which ''channel'' receives datagrams, or `#t` if datagrams are accepted on all local addresses, or `#f` if there is no such local address.  The value returned need not be the same as the value passed to `make-datagram-channel`, but must be acceptable to another invocation of `make-datagram-channel`. 
     23Returns the local endpoint or `#f` if there is none.  The value returned may not be the same as the value passed to `make-datagram-channel` (in particular, the port must not be 0), but it must be acceptable to another invocation of `make-datagram-channel`. 
    2624 
    27 `(datagram-channel-port `''channel''`)` 
     25`(datagram-channel-send-to `''channel''` `''endpoint''` `''bytevector''` `[''start'' [''end'']]`)` 
    2826 
    29 Returns the port number on which ''channel'' receives datagrams, or `#f` if there is none.  The value returned need not be the same as the value passed to `make-datagram-channel`, but must be acceptable to another invocation of `make-datagram-channel`. 
    30  
    31 `(datagram-channel-send-to `''channel''` `''host''` `''port''` `''bytevector''` `[''start'' [''end'']]`)` 
    32  
    33 Send the portion of ''bytevector'' defined by ''start'' (inclusive) and ''end'' (exclusive) to the endpoint specified by ''host'' and ''port'' using ''channel''.  If ''end'' is omitted, it is the length of ''bytevector'' plus one; if ''start'' is omitted, it is 0.  Returns undefined values.  In Posix terms this is `send()`. 
     27Send the portion of ''bytevector'' defined by ''start'' (inclusive) and ''end'' (exclusive) to ''endpoint'' using ''channel''.  If ''end'' is omitted, it is the length of ''bytevector'' plus one; if ''start'' is omitted, it is 0.  Returns undefined values.  In Posix terms this is `send()`. 
    3428 
    3529`(datagram-channel-receive-from `''channel''` `''bytevector''` `[''start'' [''end'']]`)` 
    3630 
    37 Receives a datagram from ''channel'' into the portion of ''bytevector'' defined by ''start'' (inclusive) and ''end'' (exclusive).  If ''end'' is omitted, it is the length of ''bytevector'' plus one; if ''start'' is omitted, it is 0.  Returns three values: the sending host, the sending port, and `#t` if the datagram was complete or `#f` if it was truncated.  It is an error to invoke this procedure on an output-only datagram channel.  In Posix terms this is `recvfrom()`. 
     31Receives a datagram from ''channel'' into the portion of ''bytevector'' defined by ''start'' (inclusive) and ''end'' (exclusive).  If ''end'' is omitted, it is the length of ''bytevector'' plus one; if ''start'' is omitted, it is 0.  Returns two values: the sending endpoint and `#t` if the datagram was complete or `#f` if it was truncated.  It is an error to invoke this procedure on an output-only datagram channel.  In Posix terms this is `recvfrom()`. 
    3832 
    39 `(datagram-channel-connect! `''channel''` `''host''` `''port''`)` 
     33`(datagram-channel-connect! `''channel''` `''endpoint''`)` 
    4034 
    41 Connects ''channel'' to a remote endpoint specified by ''host'' and ''port''.  Datagrams can be sent to this endpoint using `datagram-channel-send`, but it is still possible to send datagrams to other endpoints using `datagram-channel-send-to`.  When connected, a datagram channel will ignore datagrams that do not come from the specified remote endpoint.  Returns undefined values.  In Posix terms this is `connect()`. 
     35Connects ''channel'' to a remote ''endpoint''.  This endpoint may be on the local host, but it is an error for the port to be 0.  Datagrams can be sent to this endpoint using `datagram-channel-send`, but it is still possible to send datagrams to other endpoints using `datagram-channel-send-to`.  When connected, a datagram channel will ignore any arriving datagrams that do not come from the specified remote endpoint.  Returns undefined values.  In Posix terms this is `connect()`. 
    4236 
    4337`(datagram-channel-disconnect! `''channel''`)` 
     
    4539Disconnects ''channel''.  Returns undefined values.  In Posix terms this is `connect()` with an argument whose address family is `AF_UNSPEC`. 
    4640 
    47 `(datagram-channel-connected-host `''channel''`)` 
     41`(datagram-channel-remote-endpoint `''channel''`)` 
    4842 
    49 Returns the host to which ''channel'' is connected, or `#f` if there is none.  The value returned need not be the same as the value passed to `datagram-channel-connect!`, but must be acceptable to another invocation of `datagram-channel-connect!`. 
    50  
    51 `(datagram-channel-connected-port `''channel''`)` 
    52  
    53 Returns the port to which ''channel'' is connected, or `#f` if there is none.  The value returned need not be the same as the value passed to `datagram-channel-connect!`, but must be acceptable to another invocation of `datagram-channel-connect!`. 
     43Returns the remote endpoint to which ''channel'' is connected, or `#f` if it is not connected.  The value returned need not be the same as the value passed to `datagram-channel-connect!`, but must be acceptable to another invocation of `datagram-channel-connect!`. 
    5444 
    5545`(datagram-channel-send `''channel''` `''bytevector''` `[''start'' [''end'']]`)` 
    5646 
    57 Send the portion of ''bytevector'' defined by ''start'' (inclusive) and ''end'' (exclusive) to the connected endpoint of ''channel''.  If ''end'' is omitted, it is the length of ''bytevector'' plus one; if ''start'' is omitted, it is 0.  It is an error if ''channel'' is not connected.  Returns undefined values.  In Posix terms this is `send()`. 
     47Send the portion of ''bytevector'' defined by ''start'' (inclusive) and ''end'' (exclusive) to the remote endpoint of ''channel''.  If ''end'' is omitted, it is the length of ''bytevector'' plus one; if ''start'' is omitted, it is 0.  It is an error if ''channel'' is not connected.  Returns undefined values.  In Posix terms this is `send()`. 
    5848 
    5949`(datagram-channel-close `''channel''`)` 
     
    6555TFTP is a simple UDP-based protocol documented in RFC 1350.  For our purposes, all that matters is that the client sends the first datagram and the server sends exactly one response to each datagram (assuming no loss of packets in transmission). 
    6656 
    67 The server uses `(make-datagram-channel 69)` to create a datagram channel listening on UDP port 69 and then uses `(datagram-channel-receive-from `''chan''` `''bytevector''`)` to obtain an initial datagram.  The server then calls `(make-datagram-channel)` to create a new datagram channel listening on a randomly chosen port.  This datagram channel is then connected with `(datagram-channel-connect! `''client-host''` `''client-port''`)` to the client's host and port, and the initial datagram is processed and replied to.  All further transactions with that client are performed over the newly created channel. 
     57The server uses `(make-datagram-channel (make-network-endpoint 69))` to create a datagram channel listening on the local UDP port 69 and then uses `(datagram-channel-receive-from `''chan''` `''bytevector''`)` to obtain an initial datagram.  The server then calls `(make-datagram-channel)` to create a new datagram channel listening on a randomly chosen port.  This datagram channel is then connected with `(datagram-channel-connect! `''client-host''` `''client-port''`)` to the client's host and port, and the response to the initial datagram is sent on the new channel.  All further transactions with that client are performed over the newly created channel. 
    6858 
    69 The client starts by using `(make-datagram-channel)` and then `(datagram-channel-connect! `''chan''` `''host''` 69)` to connect to the server.  The initial datagram is sent with `(datagram-channel-send `''bytevector''`)`.  When the server replies, the channel is reconnected with `(datagram-channel-connect! `''host''` `''server-port''`)` and the remaining datagrams are sent over the channel. 
     59The client starts by using `(make-datagram-channel)` and then `(datagram-channel-connect! `''chan''` (make-network-endpoint `''host''` 69))` to connect to the server.  The initial datagram is sent with `(datagram-channel-send `''bytevector''`)`.  When the server replies, the channel is reconnected with `(datagram-channel-connect! (make-network-endpoint `''host''` `''server-port''`))` and the remaining datagrams are sent over the channel. 
    7060 
    7161== Issues == 
    7262 
    7363These names are very verbose, but I couldn't think of a better term than `datagram-channel`, which is borrowed from `java.nio.channels.DatagramChannel`.  This API is more powerful than Java's, though. 
    74  
    75 Shiro Kawai [http://srfi.schemers.org/srfi-106/mail-archive/msg00072.html pointed out] that having `send-to` and `receive-from` parse the ''host'' and ''port'' every time is really a performance killer, and that these should be abstracted away.  I agree, and will update this when I get a chance. 
    76