[ee122] listen()

vern at cs.berkeley.edu vern at cs.berkeley.edu
Sun Nov 25 18:25:05 PST 2007


> i am not sure about listen(). In real tcp, we set a listener, and then
> we rely on select to know when to call accept. So how are we going to
> implement listen? are we just gonna bind a port and mark it somehow as
> a listener?

First, let's review how this works for TCP:

	listen() is used to inform the kernel that your application is
	running as a server and the kernel should accept connections on
	its behalf.  It is separate from accept() so that the kernel can
	accept and queue multiple connections without the application
	having to immediately deal with them (this is why listen() takes
	a queue length as an argument).

	listen() is applicable for TCP sockets but not for UDP, because
	there's no connection-acceptance activity required by the kernel
	for UDP servers receiving requests.

	Once your application calls listen(), the kernel now knows that
	if an incoming SYN arrives for your server, it should reply with
	a SYN-ACK in an attempt to establish a connection.  If the
	corresponding ACK-SYN-ACK arrives completing the threeway handshake,
	then the kernel marks the socket as ready for "accept", and a
	subsequent call to accept() by your process will return it.

For your transport protocol, in general you would want some way for the
responder side of the connection (which receives the one-way transfer, and
because it's a responder is termed a "server" even though it doesn't itself
transmit data) to tell the kernel "yes, I want to accept incoming connections."

However, because we've said you don't in fact need to support multiple
simultaneous connections, your protocol implementation in fact doesn't
need to worry about managing multiple arriving connections.  Therefore
you can combine listen() and accept() into a single call, say
wait_for_new_connection().

> Also, since our system is not running at kernel level, can we use
> select the same way we did before, so that the user will call accept
> only when there is something in the buffer?

Because you don't have to support multiple simultaneous connections,
you won't in fact need to interface with select().

> My problem here is that
> the fd i return to the user is not a real fd, but a number that is
> used by my functions to store information about the socket. Do i have
> to create a my_select? and if that's the case can i just write an easy
> wrap around the real select?

If you have your own type of file descriptor (which makes sense for this
project, since you're not implementing in the kernel), then in fact no,
it's not easy to wrap that around the real select(), which is one of the
reasons why we've decided to limit the project to a single connection at
a time.

		Vern


More information about the ee122 mailing list