Prev Up Next
Go backward to Berkeley Sockets
Go up to Top
Go forward to A Simple Client-Server Example and Exercises

Berkeley Socket System Calls

SOCKET
This is the first action for all processes.
-It returns a socket ID (a small integer).
-It specifies the protocol (first item in an association).
-A socket ID is treated like a file descriptor in UNIX.
BIND(sock-ID,...)
This needs the socket ID from the SOCKET call.
-One argument to BIND is the local socket (=address and port) information for an association. The user can specify this local socket or specify a "NULL socket". In the latter case, the system will automatically assign a local socket and fill in this information.
-All Servers use this to register their well-known address.
-Connectionless client use this to get an address for receiving data from server.
-Connection-oriented client do not need to bind, but call connect instead.
CONNECT(sock-ID,...)
Using the above socket ID, a connection-oriented client tries to contact server.
-This operation returns with a connection (if successful).
-The caller specifies the foreight address and port.
-The local address and port are automatically assigned by the transport layer.
-Connectionless clients can also use this call,
LISTEN(sock-ID,...)
A connection-oriented server waits for clients.
-This specifies how many connection requests can be queued (while waiting for accept).
-Then server waits to accept.
ACCEPT(sock-ID,...)
This is paired up with the LISTEN call.
-It blocks until there is a connection request.
-It takes the first connection request from the queue.
-Then it creates a new socket ID with same property as the just one used up, and fill up the 5-tuple of the association. This new socket ID is returned.
-In the concurrent server, the server process would then fork, and the child process would use the new socket ID to communicate with client.
SEND, SENDTO, RECV, RECVFROM
These are similar to read/write system calls, except we read from or write into sockets.
CLOSE
This closes a socket.

Here is a code fragment for a concurrent connection-based server:

\tt
  for (;;) {
	newsockID = accept(sockID,...);
	if (newsockID<0) 
		err_sys("accept error");
	if (fork() == 0) { 		// child process
		close(sockID); 
		serve(newsockID);	// serve client
		exit(0);
	}
	// else parent process continues
	close(newsockfd);
  } // loop again
Why did the connection-oriented client skip the bind() step? Well, it does not have to skip the bind step, but then it still has to call connect(). That is, it could do socket() bind() connect() However, since the client has no particular interest in any local port, it is easier to skip the bind() step, and let the protocol assign the local port. This way, you avoid one system call. But there is a deeper reason in the case of a concurrent server: such a server forks and let the child server process serve the client (see above). The child client will use a new socket with a different port number - and this need to be communicated to the client in order for the association to be complete. However, the client does not know this BEFORE it connects.

On UNIX systems, you can obtain further information about these commands using the man command (in section 3N of the manual pages). For example:


Chee Yap

Prev Up Next