📄 sockets.tex
字号:
\begin{example} Client Opening Function \\ \label{client-opening} \verb` #include "sockets.h"` \\ \verb` typedef struct clientlist_str ClientList;`\\ \verb` struct clientlist_str {` \\ \verb` Socket *skt;` \\ \verb` ClientList *nxt,*prv;` \\ \verb` }` \\ \verb` ClientList *clhd=NULL;` \\ \verb` ClientList *cltl=NULL;` \\ \verb` ...` \\ \verb` ClientList *openClient(char *srvrname)` \\ \verb` {` \\ \verb` Socket *skt;` \\ \verb` ClientList *clist;` \\ \verb` while(1) {` \\ \verb` skt= Sopen(srvrname,"c");` \\ \verb` if(!skt) sleep(1);` \\ \verb` }` \\ \verb` clist= (ClientList *) malloc(sizeof(ClientList));` \\ \verb` if(cltl) cltl->nxt= clist;` \\ \verb` else clhd = clist;` \\ \verb` clist->prv= cltl;` \\ \verb` clist->nxt= NULL;` \\ \verb` cltl = clist;` \\ \verb` Smaskset(skt);` \\ \verb` clist->skt= skt;` \\ \verb` return clist;` \\ \verb` }` \end{example} The \verb`openClient`() function polls once~a~second in attempting to open~a~client Socket. Once it succeeds,~a~ClientList data structure is allocated, double-linked, and~a~pointer to it returned. In addition, the new client Socket is added to the Smask. \begin{example} Client Closing Function \\ \label{client-closing} \verb` void closeClient(ClientList *clist)` \\ \verb` {` \\ \verb` if(clist) {` \\ \verb` Smaskunset(clist->skt);` \\ \verb` Sclose(clist->skt);` \\ \verb` clist->skt= NULL;` \\ \verb` }` \\ \verb` }` \end{example} The \verb`closeClient`() function removes the client Socket from the Smask system, closes the Socket, and then sets the skt pointer to NULL to guarantee that the now dead socket won't be inadvertently re-used somehow. \item It is usually advisable to use some sort of handshaking protocol between server and client, especially when large data blocks are being moved. The \TCP\ buffers can easily get filled and data get lost otherwise. To facilitate this, the \SSL\ sets sockets up with the {\small TCP\_NODELAY} option so that small packets are moved out across and not collected (collection of small packets normally improves network efficiency since there's less overhead per byte of data).\end{enumerate}\newpage\section{The PortMaster}Servers have names provided by the program which opens them. When~a~server isto be opened, the Sopen function temporarily opens~a~Socket to the PortMasterrunning on the same machine. The Sopen function then tells the PortMaster theserver's {\em name} and the (random) {\em port} assigned to the new server, andthen closes down the connection. The PortMaster retains~a~list of all activeservers and ports running on its machine.A~client is opened using the Sopen function, too. In that case,~a~connectionis made to the PortMaster on the machine where the requested server isrunning. The PortMaster then tells the Sopen function the port numberassociated with the requested server, and then closes down the temporaryconnection. The Sopen function then attempts to connect to the server usingthe given port.The server program can use its server Socket to test if any clients are waitingto be connected to it (via the Stest function). If~a~client is waiting, thenthe server's program can {\em accept} the connection, generating an acceptSocket (via Saccept). Once the connection is accepted, the program attemptingto open the client Socket will finally receive~a~Socket pointer.\subsection{Users Guide}The PortMaster is probably the simplest program to run: under {\small UNIX},type \verb`Spm &` and under {\small VMS} type \verb`run/detach Spm`. ThePortMaster will only allow one copy of itself to run on any given computer. Ituses~a~fixed port address ($1750$, now registered with {\small IANA}) andimplements~a~table of server names mapping to random ports. Althoughknowledgeable users could change the PortMaster's fixed port, this isdiscouraged: hopefully, PortMasters will proliferate across the world and, ifthey all use the same port on their machines, will be able to communicate withone another. In other words, the \SSL\ will be unable to communicate withother \SSL\ systems which use~a~different port for its PortMaster.Since {\small MS-DOS} is not~a~multi-tasking operating system, unlike{\small UNIX}, {\small VMS}, or {\small Amiga-DOS}, one cannot have aPortMaster running in the background --- there is no background. Hence,{\small MS-DOS} programs are currently restricted to using client Sockets only,{\em unless} they can share another machine's PortMaster (see below).The PortMaster now supports~a~firewall: one can instruct the PortMasterto restrict access to~a~group of machines by their host addresses. See thesection on {\em The PortMaster Firewall} below.\subsection{Sharing PortMasters}PortMasters can now be {\em shared}. This feature was installed mainly tosupport {\small MSDOS} -- since it doesn't have~a~background processcapability, it cannot run PortMasters. Hence, it is normally restricted torunning clients only, because servers normally announce their presence to theirhost's PortMaster. If the environment variable \verb`PMSHARE` is set to some othermachine, that other machine's PortMaster will be used by the host's processesattempting to open servers. From the client's viewpoint, the server appears tobe on the machine with the PortMaster -- the client doesn't need to know aboutwhere the server actually is.\begin{example} PortMaster Sharing \rm \\ \label{pmsharing} \begin{tabular}{|l|l|l|} \hline \multicolumn{1}{|c|}{\bf Machine} & \multicolumn{1}{c|}{\bf Machine} & \multicolumn{1}{c|}{\bf Machine} \\ \multicolumn{1}{|c|}{\bf A} & \multicolumn{1}{c|}{\bf B} & \multicolumn{1}{c|}{\bf C} \\ \hline & & \\ PMSHARE=machineb & & \\ & & \\ opens server {\em ASrvr} & & \\ & & \\ & B's PortMaster & \\ & now has {\em ASrvr} & \\ & on its list & \\ & & \\ & & pgm opens client \\ & & to ASrvr@machineb \\ & & \\ & B's PortMaster & \\ & satisfies & \\ & client's request& \\ & & \\ & & pgm has client to \\ & & {\em ASrvr} on~A~ \\\hline \end{tabular}\end{example}In Example~\ref{pmsharing}, three machines are in use. However, machinesB~and~C~could have been the same machine. In essence, when~A~shares B'sPortMaster, the servers on~A~appear to be on~B~insofar as Sopen'ing~a~clientis concerned. Internally, of course, B's PortMaster knows where the {\em ASrvr}is, and clients end up being connected to the server on machine A.\subsection{Theory of Operation}Normally, users of the \SSL\ will not need to read this section. However,for those who are curious...There are two main benefits to using the \SSL: the functions are similarto those that the~C~programmer already knows how to use and hence the \SSL\ has~a~rapid learning curve, and second, servers are assigned to currentlyavailable ports. The PortMaster is integral to providing the second benefit.Berkeley sockets are assigned ports, which are basically just integers. Theport is used internally to assign the flow of data to the correct places.One must assign~a~specific port to~a~server or, alternatively, allow thesystem to assign any available port to it. Clients must use that same portnumber to connect to the desired server. Hence, the problem with using the``any available port'' is how to get the client process to know what thecurrently assigned port is! Programmers using Berkeley sockets have typicallyjust assigned~a~fixed port to their server and hard-coded the clients with thatport. If some other process just happens to use that same port, then thingsget messy -- re-compile, wait until the other process goes away, etc. On amachine where there are many users, co-operation between the users may beimpractical.The PortMaster solves the problem of associating~a~server name with~a~randomlyassigned (and available) port, and making that association available toclients. The PortMaster itself uses~a~fixed port, and so servers and clientsalways know ``where'' it is. Whenever~a~server opens (using the Sopen("{\smallXXX}","s") call), the Sopen function makes~a~Socket data structure, creates aBerkeley socket, initializes and binds the socket with any available port, andthen connects to the PortMaster, {\em using its fixed port}. It then sends a``message'' ({\small PM\_SERVER}, which is simply an integer) to thePortMaster, telling it the type of Socket it is. Subsequently, the PortMastergets the new server's name and the port it is assigned to.When~a~client opens, it makes~a~Socket, initializes~a~Berkeley socket as aclient (using the {\small AF\_INET} format), gets~a~``host'' entity pointer(the server's machine is known as~a~host), and then connects to the PortMasteron the host machine. It then sends~a~``{\small PM\_CLIENT}'' to thatPortMaster and the desired server's name; that PortMaster will respond with theassociated port number (if there is one). The client then closes down theconnection to the target host's PortMaster, and initializes~a~Berkeley socketwith the port number it just received and returns~a~client Socket pointer tothe user.Thus, the \SSL's PortMaster system is~a~distributed database. There areadvantages and disadvantages to this scheme. No PortMaster knows anything aboutservers residing on other machines; if~a~machine goes down, other machineswhich have no need to communicate with the downed machine are not affected.On the other hand,~a~single machine with~a~single PortMaster would obviate theneed for clients to know what machines they wish to connect to, and couldforce servers on all machines to have unique names (as it is, servers can havethe same name so long as they run on different machines). As~a~palliative, the{\em Sopenv} function supports the concept of~a~{\em machine path} via theuse of environment variables. Using the Sopenv function, clients can ``hunt''down~a~given server by attempting to open~a~client one at~a~time on each machineuntil~a~server of that name is found. Thus, the user can designate~a~localgroup of machines via an environment variable (typically, the``{\small SKTPATH}'' environment variable is used for this purpose).The PortMaster talks to its temporary clients using~a~relatively simpleprotocol based on ``messages'' (integers) defined in the \verb`sockets.h`header file. Table~\ref{portmaster} illustrates the protocol. If thePortMaster is using its firewall capability, it immediately checks all ofits temporary clients for approved machine status;~a~{\small PM\_SORRY} isissued immediately prior to the protocol in Table~\ref{portmaster} uponfailure to be approved. The connection is then summarily severed.\begin{table}[thb] \begin{center} \caption{\bf The PortMaster Protocol} \vspace{.2in} \label{portmaster} \begin{tabular}{||l|l|l||} \hline\hline \multicolumn{1}{||c|}{\em Event} & \multicolumn{1}{c|}{\em Client Sends} & \multicolumn{1}{c||}{\em PortMaster Sends} \\ \hline\hline {\small PM\_CLIENT} & & \\ & & {\small PM\_OK / PM\_RESEND} \\ & "sktname" & \\ & & {\small PM\_OK / PM\_SORRY} \\ & & port \\ \hline {\small PM\_CLOSE} & & \\ & & {\small PM\_OK / PM\_RESEND} \\ & port & \\ & & {\small PM\_OK / PM\_SORRY} \\ \hline {\small PM\_QUIT} & & \\ & & {\small PM\_OK / PM\_RESEND} \\ & "PortMaster" & \\ \hline {\small PM\_SERVER} & & {\small PM\_OK / PM\_RESEND} \\ & "sktname" & \\ & port & \\ & & {\small PM\_OK / PM\_SORRY} \\ \hline {\small PM\_TABLE} & & \\ & & {\small PM\_OK / PM\_RESEND} \\ & & count of servers \\ & & "server : port" \\ & & ... \\ \hline {\small PM\_FWINIT} & & \\ & & {\small PM\_OK / PM\_RESEND} \\ \hline\hline \end{tabular} \end{center}\end{table}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -