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