![]() |
![]()
![]() ![]() ![]()
![]() |
![]() |
4. Writing Server Applications (TCP/SOCK_STREAM)4.1 How come I get "address already in use" from bind()?You get this when the address is already in use. (Oh, you figured that much out?) The most common reason for this is that you have stopped your server, and then re-started it right away. The sockets that were used by the first incarnation of the server are still active. This is further explained in 2.7 Please explain the TIME_WAIT state., and 2.5 How do I properly close a socket?. 4.2 Why don't my sockets close?When you issue the 4.3 How can I make my server a daemon?There are two approaches you can take here. The first is to use inetd to do all the hard work for you. The second is to do all the hard work yourself. If you use inetd, you simply use If you wish to write your own server, there is a detailed explanation in "Unix Network Programming" by Richard Stevens (see 1.5 Where can I get source code for the book [book title]?). I also picked up this posting from comp.unix.programmer, by Nikhil Nair ( nn201@cus.cam.ac.uk). You may want to add code to ignore SIGPIPE, because if this signal is not dealt with, it will cause your application to exit. (Thanks to ingo@milan2.snafu.de for pointing this out).
4.4 How can I listen on more than one port at a time?The best way to do this is with the
The kernel will notify us as soon as a file descriptor which is less than
11 (the first parameter to 4.5 What exactly does SO_REUSEADDR do?This socket option tells the kernel that even if this port is busy, go ahead and reuse it anyway. It is useful if your server has been shut down, and then restarted right away while sockets are still active on its port. You should be aware that if any unexpected data comes in, it may confuse your server, but while this is possible, it is not likely. It has been pointed out that "A socket is a 5 tuple (proto, local addr, local port, remote addr, remote port). SO_REUSEADDR just says that you can reuse local addresses. The 5 tuple still must be unique!" by Michael Hunter (mphunter@qnx.com). This is true, and this is why it is very unlikely that unexpected data will ever be seen by your server. The danger is that such a 5 tuple is still floating around on the net, and while it is bouncing around, a new connection from the same client, on the same system, happens to get the same remote port. This is explained by Richard Stevens in 2.7 Please explain the TIME_WAIT state.. 4.6 What exactly does SO_LINGER do?On some unixes this does nothing. On others, it instructs the kernel to abort tcp connections instead of closing them properly. This can be dangerous. If you are not clear on this, see 2.7 Please explain the TIME_WAIT state.. 4.7 What exactly does SO_KEEPALIVE do?From Andrew Gierth ( andrew@erlenstar.demon.co.uk): The Note that the figure of 2 hours comes from RFC1122, "Requirements for Internet Hosts". The precise value should be configurable, but I've often found this to be difficult. The only implementation I know of that allows the keepalive interval to be set per-connection is SVR4.2. 4.8 How can I bind() to a port number < 1024?From Andrew Gierth ( andrew@erlenstar.demon.co.uk): The restriction on access to ports < 1024 is part of a (fairly weak) security scheme particular to UNIX. The intention is that servers (for example rlogind, rshd) can check the port number of the client, and if it is < 1024, assume the request has been properly authorised at the client end. The practical upshot of this, is that binding a port number < 1024 is reserved to processes having an effective UID == root. This can, occasionally, itself present a security problem, e.g. when a
server process needs to bind a well-known port, but does not itself need
root access (news servers, for example). This is often solved by creating
a small program which simply binds the socket, then restores the real userid
and 4.9 How do I get my server to find out the client's address / hostname?From Andrew Gierth ( andrew@erlenstar.demon.co.uk): After Jari Kokko ( jkokko@cc.hut.fi) has offered the following code to determine the client address:
4.10 How should I choose a port number for my server?The list of registered port assignments can be found in STD 2 or RFC 1700.
Choose one that isn't already registered, and isn't in /etc/services on
your system. It is also a good idea to let users customize the port
number in case of conflicts with other un-registered port numbers in other
servers. The best way of doing this is hardcoding a service name, and
using 4.11 What is the difference between SO_REUSEADDR and SO_REUSEPORT?
From Richard Stevens ( rstevens@noao.edu): This is a newer flag that appeared in the 4.4BSD multicasting code
(although that code was from elsewhere, so I am not sure just who
invented the new What this flag lets you do is rebind a port that is already in use, but only if all users of the port specify the flag. I believe the intent is for multicasting apps, since if you're running the same app on a host, all need to bind the same port. But the flag may have other uses. For example the following is from a post in February: From Stu Friedberg ( stuartf@sequent.com):
I have also heard that DEC OSF supports the flag. Also note that under
4.4BSD, if you are binding a multicast address, then From a later Stevens posting, with minor editing: Basically 4.12 How can I write a multi-homed server?The original question was actually from Shankar Ramamoorthy ( shankar@viman.com):
I want to run a server on a multi-homed host. The host is part of two networks and has two ethernet cards. I want to run a server on this machine, binding to a pre-determined port number. I want clients on either subnet to be able to send broadcast packates to the port and have the server receive them. And answered by Andrew Gierth ( andrew@erlenstar.demon.co.uk): Your first question in this scenario is, do you need to know which subnet the packet came from? I'm not at all sure that this can be reliably determined in all cases. If you don't really care, then all you need is one socket bound to
If you do care, then you have to bind multiple sockets. You are obviously attempting to do this in your code as posted, so I'll assume you do.
I was hoping that something like the following would work. Will it? This is on Sparcs running Solaris 2.4/2.5. I don't have access to Solaris, but I'll comment based on my experience with other Unixes. [Shankar's original code omitted] What you are doing is attempting to bind all the current hosts unicast addresses as listed in hosts/NIS/DNS. This may or may not reflect reality, but much more importantly, neglects the broadcast addresses. It seems to be the case in the majority of implementations that a socket bound to a unicast address will not see incoming packets with broadcast addresses as their destinations. The approach I've taken is to use This gives me very nearly what I want. The wrinkles are:
4.13 How can I read only one character at a time?This question is usually asked by people who are testing their server with telnet, and want it to process their keystrokes one character at a time. The correct technique is to use a psuedo terminal (pty). More on that in a minute. According to Roger Espel Llima
(
espel@drakkar.ens.fr), you can have
your server send a sequence of control characters:
Use of a pty would also be the correct way to execute a child process and pass the i/o to a socket. I'll add pty stuff to the list of example source I'd like to add to the faq. If someone has some source they'd like to contribute (without copyright) to the faq which demonstrates use of pty's, please email me! 4.14 I'm trying to exec() a program from my server, and attach my socket's IO to it, but I'm not getting all the data across. Why?If the program you are running uses (The short answer to this question is that you want to use a pty rather than a socket; the remainder of this article is an attempt to explain why.) Firstly, the socket buffer controlled by Perhaps the following diagram might make things a little clearer:
Assuming these two processes are communicating with each other (I've
deliberately omitted the actual comms mechanisms, which aren't really
relevent), you can see that data written by process A to it's stdio
buffer is completely inaccessible to process B. Only once the decision
is made to flush that buffer to the kernel (via The only guaranteed way to affect the buffering within process A is to change the code. However, the default buffering for stdout is controlled by whether the underlying FD refers to a terminal or not; generally, output to terminals is line-buffered, and output to non-terminals (including but not limited to files, pipes, sockets, non-tty devices, etc.) is fully buffered. So the desired effect can usually be achieved by using a pty device; this, for example, is what the 'expect' program does. Since the stdio buffer (and the A couple of alternate solutions were proposed by Roger Espel Llima ( espel@drakkar.ens.fr): If it's an option, you can use some standalone program that will just run something inside a pty and buffer its input/output. I've seen a package by the name pty.tar.gz that did that; you could search around for it with archie or AltaVista. Another option (**warning, evil hack**) , if you're on a system that
supports this (SunOS, Solaris, Linux ELF do; I don't know about others)
is to, on your main program, (Editors note: I still haven't done an expample for how to do pty's, but I hope I will be able to do one after I finish the non-blocking example code.) Previous Next Table of Contents |
||||||||||||||||
With any suggestions or questions please feel free to contact us |