[Haskell] Re: Should inet_ntoa Be Pure?
Marcin 'Qrczak' Kowalczyk
qrczak at knm.org.pl
Mon May 9 13:41:56 EDT 2005
Peter Simons <simons at cryp.to> writes:
> I would be curious to know how other programming languages
> have solved this problem. C's solution is the one we all
> know and love, and C++ added pretty much nothing to that in
> the last 10 years or so. How about others?
I once looked at .NET and was not impressed: too many variations of
types which hold various kinds of addresses, hard-coded choices which
are left more polymorphic in the BSD sockets API, and mono performs
packing and unpacking of addresses on operations.
Java also was not very interesting, I don't remember the details.
For my language Kogut I have designed and implemented the following
as a wrapper around BSD sockets (warning: not tested on real-life
applications). In a few places I rely on dynamic typing and optional
keyword parameters, so it would have to be changed a bit for Haskell.
* Address families and protocol families of type FAMILY:
InetFamily, Inet6Family (optional), and UnixFamily.
* Socket types of type SOCKET_TYPE: AnyType, DgramType,
RawType (optional), SeqPacketType, and StreamType.
* Protocols are represented by strings or numbers. Function
GetProtocolInfo resolves a protocol to a record of type
PROTOCOL_INFO with fields code, name, and aliases.
* Sockets of type SOCKET. It may be the same as RAW_FILE (currently
it is always the same). Function Socket creates an unconnected
socket. It has keyword parameters family (default: DefaultFamily,
which is Inet6Family or InetFamily by default), type (default:
StreamType), and protocol (default: depends on the family and type).
* Function SocketPair creates a pair of sockets connected to each
other. It has the same arguments as Socket.
* Addresses of type ADDRESS with fields family and data. Data is
exposed as a byte array whose format depends on the family and on
the system. Data is also exposed as a set of fields which depend
on the address family:
- InetFamily: port (0..65535), addr (a list of 4 bytes);
some constants for the addr field: InetAddrAny,
InetAddrBroadcast and InetAddrLoopback
- Inet6Family: port (0..65535), flowInfo (0..2**31-1),
addr (a list of 16 bytes), scopeId (0..2**31-1);
some constants for the addr field: Inet6AddrAny,
Inet6AddrLoopback; some predicates on the addr field:
IsInet6AddrUnspecified, IsInet6AddrLoopback,
IsInet6AddrMulticast, IsInet6AddrLinkLocal,
IsInet6AddrSiteLocal, IsInet6AddrV4Mapped,
IsInet6AddrV4Compat, IsInet6AddrMcNodeLocal,
IsInet6AddrMcLinkLocal, IsInet6AddrMcSiteLocal,
IsInet6AddrMcOrgLocal, IsInet6AddrMcGlobal
- UnixFamily: path (string)
There is a constructor Address with parameter family and
named parameters: either data or family-dependent fields. The
UnspecAddress constant can be used with Connect for clearing
the default destination of datagram sockets. Even though data
is a mutable byte array, addresses are immutable; a new array
is created each time the data field is accessed. Addresses are
compared and hashed by value.
* Function GetAddrInfo resolves a host (string) and port (string or
number) to a list of records of type ADDR_INFO with fields family,
type, protocol, address, and canonName. Either the host or the
port may be missing, but not both. Other keyword parameters of
GetAddrInfo are family (default: find out automatically), type
(default: StreamType), protocol (default: depends on the family
and type), and flags: passive, canonName, numericHost, numericServ,
v4Mapped, all, addrConfig (default: v4Mapped and addrConfig are
True, others are False).
* Function GetFirstAddrInfo returns the first element of the list
returned by GetAddrInfo.
* Function GetNameInfo translates an address to a pair of strings:
host and port. It takes keyword parameters after the address:
noFQDN, numericHost, nameReqd, numericServ, numericScope, and
dgram.
* Functions Connect and Bind take a socket and keyword parameters:
either address, or arguments for GetFirstAddrInfo.
* Function Listen takes a socket and a keyword parameter backlog
(default: DefaultBacklog, which is 5 by default).
* Function Accept takes a socket and returns a pair: a socket for
the connection and the peer address.
* Function Shutdown takes a socket and a symbol #read, #write, or
#both.
* Functions GetSocketName and GetPeerName take a socket and return
an address.
* Function SocketOption takes a socket, protocol level (SocketLevel,
IPProtoIP, IPProtoIPv6, IPProtoICMP, IPProtoRAW, IPProtoTCP,
IPProtoUDP), option name (#acceptConn, #broadcast, #debug,
#dontRoute, #error, #keepAlive, #linger, #oobInline, #rcvBuf,
#rcvLoWat, #rcvTimeO, #reuseAddr, #sndBuf, #sndLoWat, #sndTimeO,
#type, #noDelay), and either gets the socket option, or takes the
new value as the last argument and sets the option. The type of
the value depends on the option name.
* Function Receive takes a socket, byte array to fill, maximum size,
and keyword parameters: peek, oob, and waitAll; it returns a
boolean indicating the end of transmission. Function ReceiveFrom
takes the same parameters and returns the sender address or Null
if the address is unavailable.
* Function Send takes a socket, byte array to send, maximum size,
and keyword parameters: eor and oob. Function SendTo additionally
takes the recipient address after the socket.
* Function SocketStreams exposes a socket as a pair of streams:
input stream and output stream of bytes. Closing both streams
closes the socket.
* Functions SocketTextStreams and SocketBinaryStreams expose a
socket as a pair of {Text,Binary}{Reader,Writer}. They ensure that
the writer is flushed before asking for input. They take keyword
parameters for readers and writers.
* Function ClientSocket is a convenience wrapper for Socket and
Connect. Function ServerSocket is a convenience wrapper for
Socket, Bind, and Listen. They take combined keyword parameters
for the functions they use. The family of the address (if the
address is given) or the result of resolving the name (if the host
or port are given) influences the family, type and protocol of the
socket.
* Functions {ClientSocket,Accept}{,Text,Binary}Streams are
convenience wrappers for {ClientSocket,Accept} and
Socket{,Text,Binary}Streams. They take combined keyword
parameters for the functions they use.
--
__("< Marcin Kowalczyk
\__/ qrczak at knm.org.pl
^^ http://qrnik.knm.org.pl/~qrczak/
More information about the Haskell
mailing list