'\"
'\" Copyright 1989 Regents of the University of California
'\" Permission to use, copy, modify, and distribute this
'\" documentation for any purpose and without fee is hereby
'\" granted, provided that this notice appears in all copies.
'\" The University of California makes no representations about
'\" the suitability of this material for any purpose.  It is
'\" provided "as is" without express or implied warranty.
'\" 
.\" The definitions below are for supplemental macros used in Sprite
.\" manual entries.
.\"
.\" .HS name section [date [version]]
.\"	Replacement for .TH in other man pages.  See below for valid
.\"	section names.
.\"
.\" .AP type name in/out [indent]
.\"	Start paragraph describing an argument to a library procedure.
.\"	type is type of argument (int, etc.), in/out is either "in", "out",
.\"	or "in/out" to describe whether procedure reads or modifies arg,
.\"	and indent is equivalent to second arg of .IP (shouldn't ever be
.\"	needed;  use .AS below instead)
.\"
.\" .AS [type [name]]
.\"	Give maximum sizes of arguments for setting tab stops.  Type and
.\"	name are examples of largest possible arguments that will be passed
.\"	to .AP later.  If args are omitted, default tab stops are used.
.\"
.\" .BS
.\"	Start box enclosure.  From here until next .BE, everything will be
.\"	enclosed in one large box.
.\"
.\" .BE
.\"	End of box enclosure.
.\"
.\" .VS
.\"	Begin vertical sidebar, for use in marking newly-changed parts
.\"	of man pages.
.\"
.\" .VE
.\"	End of vertical sidebar.
.\"
.\" .DS
.\"	Begin an indented unfilled display.
.\"
.\" .DE
.\"	End of indented unfilled display.
.\"
'	# Heading for Sprite man pages
.de HS
.if '\\$2'cmds'       .TH \\$1 1 \\$3 \\$4
.if '\\$2'lib'        .TH \\$1 3 \\$3 \\$4
.if '\\$2'tcl'        .TH \\$1 3 \\$3 \\$4
.if '\\$2'tk'         .TH \\$1 3 \\$3 \\$4
.if t .wh -1.3i ^B
.nr ^l \\n(.l
.ad b
..
'	# Start an argument description
.de AP
.ie !"\\$4"" .TP \\$4
.el \{\
.   ie !"\\$2"" .TP \\n()Cu
.   el          .TP 15
.\}
.ie !"\\$3"" \{\
.ta \\n()Au \\n()Bu
\&\\$1	\\fI\\$2\\fP	(\\$3)
.\".b
.\}
.el \{\
.br
.ie !"\\$2"" \{\
\&\\$1	\\fI\\$2\\fP
.\}
.el \{\
\&\\fI\\$1\\fP
.\}
.\}
..
'	# define tabbing values for .AP
.de AS
.nr )A 10n
.if !"\\$1"" .nr )A \\w'\\$1'u+3n
.nr )B \\n()Au+15n
.\"
.if !"\\$2"" .nr )B \\w'\\$2'u+\\n()Au+3n
.nr )C \\n()Bu+\\w'(in/out)'u+2n
..
'	# BS - start boxed text
'	# ^y = starting y location
'	# ^b = 1
.de BS
.br
.mk ^y
.nr ^b 1u
.if n .nf
.if n .ti 0
.if n \l'\\n(.lu\(ul'
.if n .fi
..
'	# BE - end boxed text (draw box now)
.de BE
.nf
.ti 0
.mk ^t
.ie n \l'\\n(^lu\(ul'
.el \{\
.\"	Draw four-sided box normally, but don't draw top of
.\"	box if the box started on an earlier page.
.ie !\\n(^b-1 \{\
\h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul'
.\}
.el \}\
\h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul'
.\}
.\}
.fi
.br
.nr ^b 0
..
'	# VS - start vertical sidebar
'	# ^Y = starting y location
'	# ^v = 1 (for troff;  for nroff this doesn't matter)
.de VS
.mk ^Y
.ie n 'mc \s12\(br\s0
.el .nr ^v 1u
..
'	# VE - end of vertical sidebar
.de VE
.ie n 'mc
.el \{\
.ev 2
.nf
.ti 0
.mk ^t
\h'|\\n(^lu+3n'\L'|\\n(^Yu-1v\(bv'\v'\\n(^tu+1v-\\n(^Yu'\h'-|\\n(^lu+3n'
.sp -1
.fi
.ev
.\}
.nr ^v 0
..
'	# Special macro to handle page bottom:  finish off current
'	# box/sidebar if in box/sidebar mode, then invoked standard
'	# page bottom macro.
.de ^B
.ev 2
'ti 0
'nf
.mk ^t
.if \\n(^b \{\
.\"	Draw three-sided box if this is the box's first page,
.\"	draw two sides but no top otherwise.
.ie !\\n(^b-1 \h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c
.el \h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c
.\}
.if \\n(^v \{\
.nr ^x \\n(^tu+1v-\\n(^Yu
\kx\h'-\\nxu'\h'|\\n(^lu+3n'\ky\L'-\\n(^xu'\v'\\n(^xu'\h'|0u'\c
.\}
.bp
'fi
.ev
.if \\n(^b \{\
.mk ^y
.nr ^b 2
.\}
.if \\n(^v \{\
.mk ^Y
.\}
..
'	# DS - begin display
.de DS
.RS
.nf
.sp
..
'	# DE - end display
.de DE
.fi
.RE
.sp .5
..
.de UL
\\$1\l'|0\(ul'\\$2
..
.HS dp_connect cmds
.BS
.SH NAME
dp_connect, dp_shutdown, dp_accept \- Tcl-DP connection management
.sp
dp_send, dp_receive \- Stream transmission over TCP sockets
.sp
dp_packetSend, dp_packetReceive \- Message transmission using TCP sockets
.sp
dp_sendTo, dp_receiveFrom \- Message transmission using UDP sockets
.BE
.SH DESCRIPTION
.LP

This manual page describes the Tcl commands for managing basic network
connections provided by the Tcl-DP (Tcl Distributed Programming)
extension to Tcl/Tk.  These commands provide basically the same level
of service to Tcl/Tk as the UNIX C socket(2) related system
calls. The manual page is divided into two sections.  The first
section describes the commands needed to set up and shut down
connections.  The second section describes various commands for
transmitting data between machines.

All connection management commands return and take as arguments
identifiers called \fIsockId\fR's.  (A \fIsockId\fR represents a UNIX
file descriptor, which UNIX uses to represent both open
files and open sockets.  A socket is an endpoint of network
communication.)  \fISockId\fR's are identical to the identifiers
manipulated by the read, gets, puts, eof, and
close file management commands of Tcl.

.SH "CONNECTION SETUP AND TEAR DOWN"

Three basic commands are useful for connection setup and tear down:
dp_connect, dp_accept, and dp_shutdown.
Dp_connect is used to create either internet (INET) or unix domain
TCP/IP sockets, or INET based UDP/IP sockets.  If given the
\fI-server\fR flag, dp_connect creates a \fIlistening\fP socket
which other clients can connect to.  
When a remote machine attempts to connect to this listening
socket, it becomes readable.  Servers use the
dp_accept command to accept the connection, which creates a
new \fIsockId\fR connected to the client as a side effect while the
listening socket continues to listen for new connections.  Client
may close half of a duplex connection using the dp_shutdown
command.  When clients wish to terminate a connection, the tcl
close command should be used.

The rest of this sections describes the various options for
dp_connect, dp_accept, and dp_shutdown.

.TP
\fBdp_connect \fI-server\fR \fIport\fR

In this form, dp_connect creates a listening (server) socket.
This listening socket will listen for client connections on the
specified \fIport\fR number and will become readable whenever a client
process attempts a connection.  The creator of the listening socket may
then dp_accept the client connection.  (See the dp_accept
command below.  Also see the dp_filehandler and
dp_isready manual pages for testing when a socket becomes readable.)

The \fIport\fR number argument must be an unused port number.  If
the \fIport\fR number argument is empty or 0, the dp_connect
command will automatically select an unused port number.

This form of the dp_connect command returns a
list of two values.  The first value is the \fIsockId\fR that
represents the created listening socket.  The second value is the
port number that the socket is listening to.

.TP
\fBdp_connect \fI-server\fR \fIpath\fR

This command creates up a UNIX domain listening socket.  This
command is identical to the one above except that a UNIX domain
socket is created using an address specified by \fIpath\fR.

.TP
\fBdp_connect \fIhost\fR \fIport\fR

This command creates a TCP protocol INET socket and connects it
to a remote server process.  The remote server process should be
running on the machine given by the \fIhost\fR network address
and should be listening for and accepting client connections on
the given \fIport\fR number.  This command returns a list of two
values: a \fIsockId\fR to represent the newly created socket and
the port number used for the connection.

.TP
\fBdp_connect \fIpath\fR

This command creates a TCP protocol UNIX domain socket and connects it
to the UNIX domain socket specified by path.  It is otherwise identical
to dp_connect \fIhost\fR \fIport\fR.

.TP
\fBdp_connect \fI-udp\fR \fIport\fR

In this form, dp_connect creates a UDP protocol INET socket
(a connectionless socket).  Since this socket is connectionless, only the
dp_sendTo and dp_receiveFrom commands described below may
be used with this socket to transmit and receive data.

If the \fIport\fR argument is empty or 0, the system
will select an unused port number for you.  This command
returns a list containing a \fIsockId\fR (that represents the
created socket) and the \fIport\fR number (where the socket will
receive and transmit data using the UDP protocol).

.TP
\fBdp_accept \fIsockId\fR

The \fIsockId\fR argument must represent a listening (server)
socket (i.e., a \fIsockId\fR returned by the dp_connect
command that was called with the \fI-server\fR flag).  If this
listening socket is readable (i.e., a client process is
attempting to connect), the dp_accept command creates a new
socket that is connected to the client process.  If the listening
socket is not readable, th dp_accept command will block until
a client process attempts to connect to the listening socket.
The listening socket (represented by the \fIsockId\fR argument)
will remain a listening socket.  This command returns a new
\fIsockId\fR to represent the newly created socket that is
connected to the accepted client process, and the internet address
of the connecting party (eg, "128.32.149.117").  If the connection
occurs on a Unix domain socket, the second element of the
return value will be "0.0.0.0"

.TP 
\fBdp_shutdown \fIsockId\fR \fIcode\fR

Shutdown a socket for reading, writing, or both.  This command is
not the same as close, which you should use for truly
closing the socket.  The \fIsockId\fR argument must represent a
file descriptor that represents a socket, not an open file.

If \fIcode\fR is \fB"0"\fR, \fB"read"\fR or \fB"receives"\fR then
further reception of data from \fIsockId\fR will be disabled.

If \fIcode\fR is \fB"1"\fR, \fB"write"\fR or \fB"sends"\fR, then
further sending of data using \fIsockId\fR will be disabled (and
an EOF will be automatically sent down the socket).

If \fIcode\fR is \fB"2"\fR, \fB"all"\fR or \fB"both"\fR, then
further reception and sending of data on \fIsockId\fR will be
disabled.

As a side effect, the appropriate filehandlers previously
installed on the \fIsockId\fR will be deleted.  (See the
dp_filehandler man page.)

.SH "TRANSMITTING DATA"

Four pairs of commands are useful for sending and receiving data on
sockets.  The Tcl functions gets and puts can be used to
read and write string data to and from sockets.  These functions are
appropriate for communicating with text based programs (e.g., telnet).
Applications can detect closed connection when the Tcl command
eof \fIsockId\fR returns 1.

Dp_send and dp_receive are similar to gets and puts, but have the side
effect of automatically detecting closed connections.  When these
functions detect a closed connection, they remove any previously
instantiated file handlers for \fIsockId\fR and close the socket.
Applications can install callbacks associated with this "close-file"
event using the dp_atclose command.  Dp_send and dp_receive also
support non blocking input and are more efficient than gets and puts.

Dp_sendTo and dp_receiveFrom are used to send and receive data on
connectionless sockets (i.e., created using the dp_connect command
using the \fI-udp\fR option).  Dp_receiveFrom also supports non
blocking input and peeking (i.e., reading data from a socket without
advancing the file pointer).

Dp_packetSend and dp_packetReceive provide a message based protocol for
TCP sockets.  The extra protocol is necessary since TCP provides a
stream interface which does not preserve message boundaries.  The
protocol attaches an 8 byte binary header on the message containing a
magic number and the length of the message.  Due to the presence of
this header, applications should be careful about intermixing calls to
dp_packetSend and dp_packetReceive with other data transmission calls.

The options for each command are described below.

.TP
\fBdp_send\fR \fIsockId\fR \fImessage\fR ?\fInonewline\fP?

Writes the string \fImessage\fR to a connected socket.  Like the Tcl
puts command, dp_send normally outputs a newline character after
\fImessage\fR, but this feature may be suppressed by specifying the
\fInonewline\fP switch.

If insufficient buffer space exists to send \fImessage\fR, this command
will block until message is transmitted unless the socket is in
non-blocking mode (see dp_socketOption).  In this case, only part
of \fImessage\fR is transmitted.  The return value is the number of
characters sent.  The rest of the message can be sent when the socket
becomes writeable.  See the manual pages for the dp_filehandler and
dp_isready commands for testing when a socket becomes writeable.

The \fIsockId\fR argument must represent a connected (i.e., TCP
protocol) socket.  If the connection is broken, dp_send will
automatically close the socket, delete any previously created file
handlers, and return a value of 0.

.TP
\fBdp_receive\fR \fIsockId\fR ?\fInumBytes\fR? ?\fI-peek\fP?

This command reads the immediately available data from \fIsockId\fR.
If \fInumBytes\fR is specified, at most this many bytes of the
immediately available data on will be returned.  If the socket is in
non-blocking mode (see dp_socketOption) and not readable, a null string
will be returned; otherwise, the command will block until input is
received.  If \fI-peek\fP is specified, the data present on the socket
is returned but not consumed, so that a subsequent dp_receive call will
see the same data.

The \fIsockId\fR argument must represent a connected (i.e., TCP
protocol) socket.  If the connection is broken, dp_send will
automatically close the socket, delete any previously created file
handlers, and return a null string.

.TP
\fBdp_packetSend\fR \fIsockId\fR \fImessage\fR

Sends the string \fImessage\fR through the socket (\fIsockId\fR) to the
connected, remote process.  This command is similar to dp_sendTo,
except that it works with TCP sockets, so message delivery is
reliable.  It differs from dp_send in that message boundaries are
preserved.  When the remote socket calls dp_packetReceive, it will
never receive a partial \fImessage\fR.  The receiver \fImust\fP use
dp_packetReceive to read the message.

\fINotes:\fR
Message boundaries are preserved by attaching an 8 byte binary header
onto the message, half of which is a magic number indicating
a packet, and half of which indicates the size of the message.
Because this header represents binary data, care must be taken
if puts or dp_send calls are intermixed with dp_packetSend on the
same channel.

If dp_packetSend is used with non-blocking I/O mode and the send would
have blocked, dp_packetSend returns the number of bytes transmitted.
It is up to the caller to transmit the remaining characters in the
string using dp_send with the nonewline option (\fInot\fP
dp_packetSend) when the socket becomes writeable.  See dp_filehandler and
dp_isready manual pages for testing when a socket becomes writeable.)

.TP
\fBdp_packetReceive\fR \fIsockId\fR ?\fI-peek\fP?

Receives a single message from the connection (represented by the
\fIsockId\fR).  The connected, remote process which sent the message
must use the dp_packetSend command.  Dp_packetReceive differs from
dp_receive in that message boundaries are preserved.  If the entire
message is available, the return value is the message received.  If
only part of the packet is available when dp_packetReceive is called, a
zero length string is returned.  See the note in dp_packetSend above
about using dp_packetReceive and gets on the same channel.

If \fI-peek\fP is specified, the data present on the socket is returned
but not consumed, so that a subsequent dp_packetReceive calls will
see  the same data.

If no data is available at the socket and the socket is in non blocking
mode, a zero length string is returned.  Otherwise, this operation
blocks until at least some data (but possibly not the entire packet)
is received.

.TP
\fBdp_sendTo\fR \fIsockId\fR \fImessage\fR \fIaddr\fR

Sends the string \fImessage\fR to the process at the destination
address specified by the \fIaddr\fR handle.  The \fIaddr\fR handle must
be created using the dp_address command or taken from the return
value of the dp_receiveFrom command.  The \fIsockId\fR argument
must represent a connectionless socket (i.e., created using the
dp_connect command using the \fI-udp\fR option).  Dp_sendTo
uses \fIsockId\fR as the transmitting socket.

.TP
\fBdp_receiveFrom\fR \fIsockId\fR ?\fInumBytes\fR? ?\fI-peek\fR? ?\fI-noaddr\fR?

Receives a message that was sent from another process that used the
dp_sendTo command.  Normally, a list of two values is returned.  The
first value is the address (an \fIaddr\fR handle) of the sending
process, and the second element is the message received.  If the
\fI-noaddr\fR flag is specified, the address of the sending process is
ommitted.  If the socket is in non-blocking mode (see dp_socketOption)
and not readable, -1 will be returned.  Otherwise, this command will
block until a message arrives.  If \fI-peek\fR is specified, the
message is read from the socket but not removed from the queue.  If
\fInumBytes\fR is specified, at most this many bytes of the message is
returned.  Because of the way connectionless sockets work, the rest of
the datagram will be discarded from the queue, regardless of the value
of \fInumBytes\fR, unless \fI-peek\fR is specified.

The \fIsockId\fR argument must represent a connectionless socket
(i.e., created using the dp_connect command using the
\fI-udp\fR option).  The dp_receiveFrom command uses the
connectionless socket, \fIsockId\fR, as the reception socket.

.SH SEE ALSO
Tcl-DP, socket(2), accept(2), connect(2), listen(2), dp_address(n),
Tcl, dp_filehandler(n), dp_socketOption(n)

.SH AUTHOR
Pekka Nikander, Telecom Finland (Pekka.Nikander@ajk.tele.fi)
.br
Extended by Tim MacKenzie (tym@dibbler.cs.monash.edu.au)
.br
Further enhancements by Brian Smith (bsmith@cs.berkeley.edu),
.br
Steve Yen (syen@cs.berkeley.edu), and
.br
Lou Salkind (salkind@deshaw.com)
