|
|
Connection establishment is usually asymmetric, with one process a client and the other a server. The server, when willing to offer its advertised services, binds a socket to a well-known address associated with the service and then passively listens on its socket. It is then possible for an unrelated process to rendezvous with the server. The client requests services from the server by initiating a connection to the server's socket. On the client side the connect call is used to initiate a connection. In the UNIX domain, this might appear as:
struct sockaddr_un server; ... connect(s, (struct sockaddr *)&server, strlen(server.sun_path) + offsetof(struct sockaddr_un, sun_path));while in the Internet domain, it might be:
struct sockaddr_in server; ... connect(s, (struct sockaddr *)&server, sizeof(server));server would contain either the UNIX pathname, or the Internet address and port number of the server to which the client process wishes to speak. If the client process's socket is unbound at the time of the connect call, the system will automatically select and bind a name to the socket if necessary. See ``Signals and process groups'' below. This is the usual way that local addresses are bound to a socket.
An error is returned if the connection was unsuccessful (however, any name automatically bound by the system remains). Otherwise, the socket is associated with the server and data transfer may begin. Some of the more common errors returned when a connection attempt fails are:
struct sockaddr_in from; ... listen(s, 5); fromlen = sizeof(from); newsock = accept(s, (struct sockaddr *)&from, &fromlen);The first parameter to the listen call is the socket on which the connection is to be established. The second parameter to the listen call specifies the maximum number of outstanding connections that may be queued awaiting acceptance by the server process. (For the UNIX domain, from would be declared as a
struct sockaddr_unbut nothing different would need to be done as far as fromlen is concerned. In the examples that follow, only Internet routines will be discussed.) A new descriptor is returned on receipt of a connection (along with a new socket). If the server wishes to find out who its client is, it may supply a buffer for the client socket's name. The value-result parameter fromlen is initialized by the server to show how much space is associated with from. It is then modified on return to reflect the true size of the name. If the client's name is not of interest, the second parameter may be a null pointer.
accept normally blocks. That is, accept will not return until a connection is available or the system call is interrupted by a signal to the process. Further, there is no way for a process to show that it will accept connections only from a specific individual or individuals. It is up to the user process to consider who the connection is from and close down the connection if it does not want to speak to the process. If the server process wants to accept connections on more than one socket, or wants to avoid blocking on the accept call, there are alternatives; they will be considered in ``Advanced topics''.