9fans archive / 1998 / 12 / 15 /    prev next

From: Franklin Robert Araujo França 973930@dcc...
Subject: [9fans] BSD Sockets: Accept and Connect
Date: Mon, 14 Dec 1998 16:21:11 +0000

    I wrote the following programs using BSD Sockets in Plan 9:

SERVER.C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <time.h>
#include <sys/time.h>
#include <unistd.h>

#define MAXLINE   4096
#define SERV_PORT 9877
#define LISTENQ   1024

void str_echo(int);

int main(int argc, char **argv)
{
  int data, control, newdata, newcontrol;
  int listenfd, connfd;
  pid_t childpid;
  int clilen;
  struct sockaddr_in cliaddr;
  struct sockaddr_in servaddr;

  listenfd = socket(AF_INET, SOCK_STREAM, 0);
  bzero(&servaddr, sizeof(servaddr));
  servaddr.sin_family = AF_INET;
  servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
  servaddr.sin_port = htons(SERV_PORT);
  bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
  listen(listenfd, LISTENQ);

  for(;;){
     clilen = sizeof(cliaddr);
     connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &clilen);
     if((childpid = fork()) == 0) { /*child process */
       close(listenfd); /*close listening socket*/
       str_echo(connfd); /*process the request*/
       exit(0);
     }
     close(connfd); /*parent closes connected socket*/
  }
}

void str_echo(int sockfd)
{
  char line[MAXLINE];
  int n;

  for(;;){
      if ((n = read(sockfd, line, MAXLINE)) == 0)
         return; /*connection closed by other end */
      write(sockfd, line, n);
  }
}

**********************
CLIENT.C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <time.h>
#include <sys/time.h>
#include <unistd.h>

#define MAXLINE 4096
#define SERV_PORT 9877

void str_cli(FILE *, int);

int main(int argc, char **argv)
{
  int sockfd, i;
  struct sockaddr_in servaddr;
  struct hostent *host;
for(i=0; i< 20; i++){
  sockfd = socket(AF_INET, SOCK_STREAM, 0);
  bzero(&servaddr, sizeof(servaddr));
  servaddr.sin_family = AF_INET;
  servaddr.sin_port = htons(SERV_PORT);
  host = gethostbyname(argv[1]);
  bcopy(host->h_addr, (char *) &servaddr.sin_addr, host->h_length);

  if (connect(sockfd, &servaddr, sizeof(servaddr)) < 0){
      perror("client connect:");
      exit(1);
  }
}
  str_cli(stdin, sockfd); /*do it all */
  exit(0);
}

void str_cli(FILE *fp, int sockfd)
{
  char sendline[MAXLINE], recvline[MAXLINE];

  while (fgets(sendline, MAXLINE, fp) != NULL) {
       write(sockfd, sendline, strlen(sendline));

       if (read(sockfd, recvline, MAXLINE) == 0)
          perror("str_cli: server terminated prematurely");

        fputs(recvline, stdout);
   }
}



SERVER2.C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <time.h>
#include <sys/time.h>
#include <unistd.h>

#define MAXLINE   4096
#define SERV_PORT 9877
#define LISTENQ   1024

void str_echo(int);

int main(int argc, char **argv)
{
  int data, control, newdata, newcontrol;
  int listenfd, connfd;
  pid_t childpid;
  int clilen;
  struct sockaddr_in cliaddr;
  struct sockaddr_in servaddr;

  listenfd = socket(AF_INET, SOCK_STREAM, 0);
  bzero(&servaddr, sizeof(servaddr));
  servaddr.sin_family = AF_INET;
  servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
  servaddr.sin_port = htons(SERV_PORT);
  bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
  listen(listenfd, LISTENQ);

  for(;;){
     clilen = sizeof(cliaddr);
     connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &clilen);
       str_echo(connfd); /*process the request*/

   close(connfd); /*parent closes connected socket*/
  }
}



void str_echo(int sockfd)
{
  char line[MAXLINE];
  int n;

  for(;;){
      if ((n = read(sockfd, line, MAXLINE)) == 0)
         return; /*connection closed by other end */
      write(sockfd, line, n);
  }
}


    The difference between the servers is that the SERVER.C, for each
client,  use a child process that handles the new client, and the
SERVER2.C use only one child process.

    The programs works on Linux, but only the first server (SERVER.C)
works on Plan 9. The client communicating with the second server (SERVER
2) crashs when it try connect to the server for the seventh time:
connect: invalid argument.

Franklin.