Business IT - Technology for your business

No. 1 Story

Cloud alliance sides with Optus on copyright

OzHub, the Macquarie Telecom-led cloud computing alliance, has come down firmly on the side of Optus over the copyright controversy surrounding Optus TV Now, warning that any moves to change the law "risk branding Australia a global luddite state."

read more

Write your own Linux server part two

Business IT - Open Source

In part one, we presented a real-world story where a Linux server – or daemon – solved a need for an ISP. The code to achieve this was introduced, and annotated. However, we left the best till now – the actual socket handling itself, plus the rc.d script to start the daemon at boot time and kill it at shutdown.

free hit counter
Socket handling


This daemon, like any other, is designed to run in the background, and respond to network connections over TCP/IP. We can achieve this using the best known TCP/IP handling interface, Berkeley sockets. Our main() routine in dwserv.cpp sets it all up.


int main (int argc, char *argv [])
{
  struct sockaddr_in sin, fsin;
  struct protoent *ppe;
  int sock, ssock;
  int alen;
  int port = 5000;
  int qlen = 5;
  int pid;
  int fd;
  char nowtime [26];
  char Remote [80];
  int connections = 0;
  FILE *logfp = NULL;


First, as we are going to be creating accounts, the server must be run as the super-user. However, this need not cause any fear, because our server is both robust and secure. And, of course, it is open source and can thus be inspected and enhanced.

  if (geteuid () != 0)
  {
    printf ("\n%s must be run with super-user privileges.\n", argv [0]);
    return 0;
  }


We then establish a server socket, bound to the port we have chosen to use, as specified by the port variable above.

// Set up the socket.

  sin.sin_family = AF_INET;
  sin.sin_addr.s_addr = INADDR_ANY;
  sin.sin_port = htons (port);

  if ((ppe = getprotobyname ("tcp")) == 0)
    errexit ("Can't find tcp: %s\n", strerror (errno));

  if ((sock = socket (PF_INET, SOCK_STREAM, ppe->p_proto)) < 0)
    errexit ("Can't create socket: %s\n", strerror (errno));

  if (bind (sock, (struct sockaddr *) &sin, sizeof (sin)) < 0)
    errexit ("Can't bind to port: %s\n", strerror (errno));

  if (listen (sock, qlen) < 0)
    errexit ("Can't listen on port: %s\n", strerror (errno));


We set the server to run in the background by using the fork system call to create a second process, and by disconnecting the new process from the controlling tty. The original process is terminated.


  if ((pid = fork ()) < 0)
    errexit ("Error setting up server: %s\n", strerror (errno));

  if (pid)  // Non-zero is parent.
  {
    printf ("Server pid is %d.\n", pid);
    if (strlen (FileName) > 0)
      log ("Server pid is %d.\n\n", pid);
    exit (0);
  }

  fd = open ("/dev/tty", O_RDWR);
  ioctl (fd, TIOCNOTTY, 0);
  close (fd);


The server now simply sits passively in the background listening forever for network connections.


If an incoming request is made, then a new, slave, socket is created to process it. This is hived off into a child process. This permits the server socket and process to continue accepting more connections because it has offloaded the processing. This gives the appearance of allowing multiple simultaneous connections.


  while (1)
  {
    alen = sizeof (fsin);
    ssock = accept (sock, (struct sockaddr *) &fsin, &alen);
    if (ssock < 0)
    {
      if (errno == EINTR)
        continue;
      else
        errexit ("accept: %s\n", strerror (errno));
    }

    strcpy (Remote, IPtoAddress (fsin.sin_addr));
    log ("%s: connect from %s\n", CurrentDateTime (nowtime), Remote);

    signal (SIGCHLD, reaper);
    connections++;
    if (fork () == 0)
    {
      process (ssock, Remote, connections);
      exit (0);
    }
    else
      close (ssock);
  }
}


The process method, called above, deciphers the command received from the client and calls the appropriate method to deal with it - such as CreateAccount. Any error messages are returned to the client through the same socket.



- sponsored feature -

The Death of Traditional BI: What’s Next?

How to Make Business Discovery Work for Your Business IP PABX BUYING GUIDE

Business Discovery takes its cues from consumer apps. Like Google, it encourages us- ers to hunt for and explore data without worrying about or even noticing the underly- ing technology. Their entire experience is working within an intuitive interface to get real-time, self-service results with only minimal training. ...more