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. SOCK: SOCK *next ptr to next SOCK (for linked list) DEST: *dest DEST info for this sock 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.