マルチプルアクセス可能なサーバ

  概要   プログラム   解説

プログラム

/***********************************************************************
   mserver.c : Multiple Connection Server program
   Jan 8,2001  copyright Takeshi FUJIKI (fujiki@fc-lab.com)
   チャットするプログラム
***********************************************************************/
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <fcntl.h>
#include <sys/time.h>

#define MaxClient 7
#define BUFLEN 256
#define ListenPort 7000
#define NotUsed -1

int main(int argc, char* argv[]) {
  struct hostent *thishost;
  struct sockaddr_in me;
  char hostname[80],buf[BUFLEN];
  int listen_socket, option, length, i, j;
  int client_socket[MaxClient],n_client, max_fd;
  fd_set readmask;
  struct timeval timeout;

  listen_socket = socket(AF_INET,SOCK_STREAM,0);
  option = 1;
  setsockopt(listen_socket,SOL_SOCKET,SO_REUSEADDR,&option,sizeof(option));
  gethostname(hostname,80);
  thishost = gethostbyname(hostname);
  bzero((char *)&me,sizeof(me));
  me.sin_family=AF_INET;
  me.sin_port = htons(ListenPort);
  bcopy(thishost->h_addr,(char *)&me.sin_addr,thishost->h_length);
  bind(listen_socket,&me,sizeof(me));
  listen(listen_socket,MaxClient);


  for (i=0;i<MaxClient;i++)
    client_socket[i] = NotUsed;
    
  client_socket[0] = 0;
  max_fd = listen_socket;

  while(1) {
    FD_ZERO(&readmask);
    FD_SET(listen_socket,&readmask);
    for (i=0;i<MaxClient;i++) {
      if (client_socket[i] != NotUsed)
	FD_SET(client_socket[i],&readmask);
    }

    timeout.tv_sec = 60;
    timeout.tv_usec = 0;
    switch(select(max_fd+1,&readmask,NULL,NULL,&timeout)) {
    case -1: /* エラーの場合 */
      printf("Error\n");
      break;
    case 0: /* timeoutの場合 */
      printf("Timeout\n");
      break;
    }

    if (FD_ISSET(listen_socket,&readmask)) {
      int free_index = -1;
      for (i=0;i<MaxClient;i++)
	if (client_socket[i] == NotUsed) {
	  free_index=i;
	  break;
	}
      if (free_index != -1) {
	client_socket[free_index] = accept(listen_socket,NULL,NULL);
	if (client_socket[free_index] > max_fd)
	  max_fd = client_socket[free_index];
	sprintf(buf,"Welcome! You are User%d\n",free_index);
	write(client_socket[free_index],buf,strlen(buf));
      }
    } else {
      for (i=0;i<MaxClient;i++) {
	if ((client_socket[i] != NotUsed)
	    && FD_ISSET(client_socket[i],&readmask)){
	  length = read(client_socket[i],buf,BUFLEN);
	  if (length == 0){
	    close(client_socket[i]);
	    client_socket[i] = NotUsed;
	  } else {
	    char user[80];
	    sprintf(user,"user%d : ",i);
	    for(j=0;j<MaxClient;j++)
	      if ((j != i) && (client_socket[j] != NotUsed)) {
		write(client_socket[j],user,strlen(user));
		write(client_socket[j],buf,length);
	      }
	  }
	}
      }
    }
  }
  close(listen_socket);
  for (i=0;i<MaxClient;i++)
    if (client_socket[i] != NotUsed)
      close(client_socket[i]);
}


  

  
FC Labのホームへ 「ネットワークプログラミング」のページへ