Документ взят из кэша поисковой машины. Адрес оригинального документа : http://www.naic.edu/~phil/software/datataking/socklib
Дата изменения: Wed Nov 25 01:17:24 2009
Дата индексирования: Thu Apr 8 14:35:02 2010
Кодировка:

Поисковые слова: annular solar eclipse
Notes on jeffs socklib:
file: /home/phil/Linux/libsrc/socklib/Notes

Initialization:
-sock_bind() calls find_dest that calls init_dest() to read in the
mailbox file.
- binding sets up the socket for you to receive things on.
- The name/port can be in the mailbox file. This way people can
contact you.
- the name can be anonymous. In this case you need to send the
name/port to people before they can contact you.

I/O:
- The read/write calls are done in sock_read and sock_write. All other
routines go thru here. On error the socket is closed.
- I/O Message format
- 4 byte int holding message length followed by this many bytes (the
1st 4 bytes are not included in the message length). The message
length is sent in network byte order.
- Accepting new socket..
when we get a new socket on the listen socket, the first message
we receive must be the mailbox name of the person making
the socket connection. This is handled in accept_sock().
It will link the socket into our bound SOCK* linked list
(by calling sock_connect().
- READS:
-The maximum allowable read length is defined as a variable in bound
struct: bufct. This is the maximum allowable bytes for a message.
It is Used to check when we are out of sync.
- The user passes in the buffer to read into (variable: message).
It must have already been allocated. It should always be at
least bufct bytes since the read will clip if the message length
is > bufct bytes. The length of the current message buffer is
not passed in.
- Actually the read buffer should always be bufct+1 since
it puts a null at msg[count]
-If there is a read error, the socket is closed. Sockets that are
closed get s->fd=-1. -2 is returned as status.
- If things are ok, the fd that was just read is returned.
-WRITES: sock_write
- you pass in *SOCK.
loop:
- if the fd in SOCK has not yet been opened and we are not
an anonymous socket..
- allocate socket,
- bind any port number to it.
- connect to address.
- send message telling them our mailbox name.
- It writes the message count followed by the message.
- if there byte count sent does not equal the requeseted number
of bytes then the socket is closed and the loop: is repeated
(at most once). This tries to recover from things like
computer reboots.


SOCKET OPTS:
- fcntl (F_SETFD,FD_CLOEXEC) close on exec`
- sockopt so_reuseaddr
- listen (max=5).
SELECT:
sock_sel() - calls sock_ssel().blocks waiting for message then reads.
same as sock_ssel() but does not support the
exclude sockets (ss)
sock_ssel()-: select then read:
: select on sockets in bound struct (including listen socket).
: user can specifiy sockets in bound struct to ignore.
these will not be included in the select.
: user can specifiy extra sockets (p) to select on
` : select with timeout.
: if listen socket then sock_accept()
: if one of the p (extra) sockets, just return with the
fd
: call sock_read to read the message
sock_fastsel: looks like same as sock_sel() except that the timeout
is already in the time struct format rather than sec/usecs
sock_only() : user specifies a SOCK struct to wait on. It then
waits on only this and the listen socket.
sock_poll() :


ERRORS:
-The routine ph->error() is called with the error message when an error
returns. We always return from this call (unless the user does something
funny with there own version of standard_error).
-The default routine is standard_error() set in init. This just
writes to stderr. You can change this destination with the routine
sock_seterror().
-Errors in read/write will close the offending socket. This includes
message lengths longer than the requested length (usually means you're
out of sync).

------------------------------------------------------------------------------
STRUCTURES:
------------------------------------------------------------------------------
DEST:
int dport port number
char host[30] hostname (as in host file)
char dname[30] service name. Users use this name as identifier.
comes out of the mailbox file.

SOCK:
SOCK *next ptr to next SOCK (for linked list)
DEST: *dest DEST info for this sock (who connected to us)
fd int for this socket (-1 -->> closed)
sin structaddr_in sin: sin.port.. passed to bind call.

BOUND:
int bind_fd; fd we bind for listening.
DEST: *dest DEST struct for bound socket (bind_fd).
SOCK: *head head of linked list of sockets we've done accepts on.
struct sockaddr_in sin: sock addr for bind_fd.
int bufct; max length for a message (excluding 4 byte length)
default is 4096. All message buffers malloced by users
should be at least this long (actually 4096+1).
int interrupt; If true then sock_sel select will return with stat=-3
on an interrupt EINTR during the select wait. if 0
it keeps looping
int isxview; 1 if xview ...
int isaio ; 1 if aioread is turned on (solaris).
int (*open)(struct SOCK *,int) called after accept or before connect
if not null. user supplied.
int (*close)(int fd) user supplied called before os close().
int (*error)(char *,char*) user supplied routine to call on error
default is standard_error() which just prints to
stderr. First arg is format string (printf) with
at most a %s format descriptor. 2nd arg is
the variable for %s or null.
-----------------------------------------------------------------------------
How it is used:
------------------------------------------------------------------------------
To receive info:

0. The socklib.c code declares the globals:
struct BOUND sock_bound and
struct BOUND *bs = &sock_bound
This is the root for all sockets.
There is only 1 bound structure for each program. the
top level is that programs listen socket, all socket connections
from outside have socket structs linked in o the SOCK *next
list.
It uses stream sockets..


1. A progran calls sock_bind (or bindsock for tk) with it's mail box name.
It creates the listen socket with a socket() call, fills in the address info,
calls bind on bs->bind_fd, fills in the bs-> dest address info for the listen socket
and the calls listen(bs->bind_fd)


2. The user then calls accept_sock(0) (or maybe via sock_sel().
a. calls accept:
b. reads the first message which should be:
msgLen,mailBoxName of sender

c. calls sock_connect(mbnameOfSender) to malloc a SOCK struct and link it into
bs->next. Note this is not the normal socket connect() call. It just links
the new socket into the bs->next list.
d. It will call the open routine specifed (if specified) with
(bs->open)(s,s->fd) where SOCK *s is the new SOCK entry.
Note that there is one open routine for all sockets connected.
3. then sock_sel or sock_ssel to wait for input from all open sockets.

To send info:
;
1. go through the bind for your own address.
2. If you are replying to a message:
s=last_msg() will give SOCK struct of last caller
else
s=sock_connect(mbName);
this will link the SOCK structure for this person into our bs->head.
The fd is not yet open.
endif
sock_send(s,message).
If s->fd < 0 then it will try to open a socket for us and link
it in. It will do a bind any on this SOCK since we don't recieve on it.





-----------------------------------------------------------------------------
Protocol:
------------------------------------------------------------------------------
1. user wants to talk to cima. without socklib

get port number for executive,computer

connect()
msg={int msglen,
char *msg
}
switch message to network order
write(fdex,message) ..
;
need a mailbox name that cima knows about (adn the cpu??)