[[MinGWによるWindows Programming]]

 /* srv.c */
 
 #define STRICT
 #include <stdio.h>
 #include <string.h>
 #include <time.h>
 
 #ifdef WIN32
 #include <windows.h>
 #include <winsock.h>
 #include <process.h>
 #else
 #ifdef SOLARIS
 #include <thread.h>
 #else
 #include <pthread.h>
 #endif
 #include <netdb.h>
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 typedef int SOCKET;
 #define INVALID_SOCKET (-1)
 #endif
 
 /*---------------------------------------------------
  * Program:
  *   simple tcp server
  *
  * Purpose:
  *   Socket and multi-thread application program
  *   that acts as a server for the tcp service on
  *   the local machine.  It listens on port SERV_TCP_PORT
  *   and answers according to the command from clients.
  *
  * Use:
  *   testsrv
  *
  * Author:
  *   Based on the program by Barry Shein, Boston University
  *   Modified for Win32-console and winsock by Hirofumi Fujii, KEK
  *
  * Date:
  *   Original Version - January, 1987
  *   Modified for Win32-console and winsock - January, 1997
  *
  * Reference:
  *   Comer, Douglas E.,
  *   Internetworking with TCP/IP Vol. I, 2nd. Ed.,
  *   Section 21.27, pp. 359-362, Prentice-Hall (1991),
  *   ISBN 0-13-468505-9.
  *
  * Comile and Link:
  *   MinGW
  *   gcc -DWIN32 srv.c -lwsock32 -o srv.exe
  *
  *   Microsoft Visual C++ 4.0
  *   cl /MT /W3 /DWIN32 srv.c wsock32.lib
  *
  *   Digital UNIX V3.2D-1 (Rev. 41)
  *   cc srv.c -o srv -threads
  *
  *   SunOS 5.4
  *   cc -DSOLARIS srv.c -o srv -lthread -lsocket
  */
 
 #define BACKLOG   5     /* number of requests we're willing to queue */
 #define MAXCMDLINE 256  /* maximum command line length */
 #define SERV_TCP_PORT 6543
 
 #ifndef WIN32
 void
 closesocket( SOCKET s )
 {
   close( s );
 }
 #endif
 
 int
 netstart( void )
 {
 #ifdef WIN32
   WSADATA wsadata;
   WORD wsaversion;
 
   wsaversion = 0x0101;
   return( WSAStartup( wsaversion, &wsadata ) );
 #else
   return 0;  /* Always no error */
 #endif
 }
 
 void
 netclose( SOCKET sockfd )
 {
 #ifdef WIN32
   if( sockfd != INVALID_SOCKET )
     closesocket( sockfd );
   WSACleanup();
 #else
   if( sockfd >= 0 )
     close( sockfd );
 #endif
   return;
 }
 
 void
 server( void *s )
 {
   SOCKET sock;
   char rbuf[BUFSIZ+1];
   char sbuf[BUFSIZ+1];
   char cmnd[MAXCMDLINE+1];
   int i;
   int ncmnd;
   int nrecv;
   int nsend;
   time_t tnow;
   
   /* Copy the socket */
   sock = (SOCKET)s;
   
   ncmnd = 0;
   while(1)
   {
     /*
      * Get one line request
      */
     if((nrecv = recv( sock, rbuf, BUFSIZ, 0 )) <= 0 )
     {
       closesocket( sock );
 #ifdef WIN32
       _endthread();
 #else
       return;
 #endif
     }
     /*
      * Fill command line
      */
     for( i = 0; i < nrecv; i++ )
     {
       if((rbuf[i] == 0x0d) || (rbuf[i] == 0x0a))
       {
         /* ASCII-CR or ASCII-LF */
         cmnd[ncmnd] = '\0'; /* Null terminate */
         /*
          * Return reply
          */
         if( strcmp( "exit", cmnd ) == 0 )
         {
           closesocket( sock );
 #ifdef WIN32
           _endthread();
 #else
           return;
 #endif
         }
         else if( strcmp( "date", cmnd ) == 0 )
         {
           time( &tnow );
           strcpy( sbuf, ctime( &tnow ) );
           nsend = strlen( sbuf );
           if( sbuf[nsend - 1] == 0x0a )
             nsend--;
           if( sbuf[nsend - 1] == 0x0d )
             nsend--;
           sbuf[nsend++] = 0x0d;
           sbuf[nsend++] = 0x0a;
           sbuf[nsend] = '\0';
           send( sock, sbuf, nsend, 0 );
         }
         else if( ncmnd > 0 )
         {
           sprintf( sbuf, "OK\015\012" );
           send( sock, sbuf, strlen( sbuf ), 0 );
         }
         ncmnd = 0;
       }
       else if( (rbuf[i] >= ' ') && ((rbuf[i] & 128) == 0) )
       {
         if( ncmnd < MAXCMDLINE )
           cmnd[ncmnd++] = rbuf[i];
       }
     }
   }
 }
 
 int
 main( int argc, char *argv[] )
 {
   SOCKET s, t;     /* socket descriptors */
   int i;           /* general purpose integer */
   struct sockaddr_in sa, isa;    /* Internet socket addr. structure */
   char *myname;    /* pointer to name of this program */
 #ifndef WIN32
 #ifdef SOLARIS
   thread_t thread;
 #else
   pthread_t thread;
 #endif
 #endif
 
   myname = argv[0];
   /*
    * Load the TCP/IP module (winsock)
    */
   if( netstart() != 0 )
   {
     fprintf( stderr, "%s: cannot load the network module.\n", myname );
     exit(1);
   }
   /*
    * Put the socket number and our address info
    * into the socket structure
    */
   memset((char *)&sa, 0, sizeof(sa));
   sa.sin_family = AF_INET;
   sa.sin_port = htons( SERV_TCP_PORT );
   sa.sin_addr.s_addr = htonl( INADDR_ANY );
   /*
    * Allocate an open socket for incoming connections
    */
 #ifdef WIN32
   if( (s = socket( AF_INET, SOCK_STREAM, 0 )) == INVALID_SOCKET )
 #else
   if( (s = socket( AF_INET, SOCK_STREAM, 0 )) < 0 )
 #endif
   {
     netclose( s );
     fprintf( stderr, "%s: Cannot allocate socket\n", myname );
     exit(2);
   }
   /*
    * Bind the socket to the service port
    * so we hear incoming connections
    */
 #ifdef WIN32
   if( bind( s, (const struct sockaddr *)&sa, sizeof( sa ) ) == SOCKET_ERROR )
 #else
   if( bind( s, (const struct sockaddr *)&sa, sizeof( sa ) ) < 0 )
 #endif
   {
     netclose( s );
     fprintf( stderr, "%s: Cannot bind the socket.\n", myname );
     exit(2);
   }
   /*
    * Set maximum connections we will fall behing
    */
   listen( s, BACKLOG );
   /*
    * Go into an infinite loop waiting for new connections
    */
   while(1)
   {
     i = sizeof( isa );
     /*
      * We hang in accept() while waiting for new customers
      */
 #ifdef WIN32
     if((t = accept( s, (struct sockaddr *)&isa, &i )) == INVALID_SOCKET )
 #else
     if((t = accept( s, (struct sockaddr *)&isa, &i )) < 0 )
 #endif
     {
       netclose( s );
       fprintf( stderr, "%s: Cannot accept the connetion.\n", myname );
       exit(2);
     }
     /* create and start the new thread */
 #ifdef WIN32
     _beginthread( server, 0,(void *)t );
 #else
 #ifdef SOLARIS
     thr_create( NULL, 0, server, (void *)t, (long)0, &thread );
 #else
     pthread_create( &thread, pthread_attr_default,
       (pthread_startroutine_t)server, (pthread_addr_t)t );
 #endif
 #endif
   }
 }
 

Clinet 側は telnet で行えばよい。


トップ   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS