selectシステムコールを使ったTCPサーバ



::::::::::::::
Makefile
::::::::::::::
# $Id: select.html,v 1.1 2009/06/22 16:12:25 kishi Exp kishi $
# @author KISHI Yasuhiro

CFLAGS = -c -Wall -O2
OBJECT1 = Server.o 
EXE1 = Server.exe
OBJECT2 = Client.o 
EXE2 = Client.exe

all: Server Client

Server: $(OBJECT1)
	gcc $(OBJECT1) -o $(EXE1) && strip $(EXE1)

Server.o:  Server.c
	gcc $(CFLAGS) Server.c

Client: $(OBJECT2)
	gcc $(OBJECT2) -o $(EXE2) && strip $(EXE2)

Client.o:  Client.c
	gcc $(CFLAGS) Client.c

clean:
	rm -f *.o *.exe *~ *.bak *.orig

indent:
	astyle -c -a -P *.c


::::::::::::::
Client.c
::::::::::::::
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <sys/un.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>

/** $Id: select.html,v 1.1 2009/06/22 16:12:25 kishi Exp kishi $ */

int main( int argc, char** argv ) {
    int sockfd;
    int len;
    struct sockaddr_in address;
    int result;
    char ch = 'X';
    int portNumber;

    if ( argc != 2 ) {
        fprintf( stderr, "Usage: %s [portNumber]\n", argv[ 0 ] );
        return 1;
    }
    portNumber = atoi( argv[ 1 ] );

    sockfd = socket( AF_INET, SOCK_STREAM, 0 );
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = inet_addr( "127.0.0.1" );
    //-----------------------------------------------------------------
    // htonl() is usually used, but this is cygwin's case
    //-----------------------------------------------------------------
    address.sin_port = htons ( portNumber );

    len = sizeof( address );
    result = connect( sockfd, ( struct sockaddr* ) & address, len );
    if ( result == - 1 ) {
        perror( "oops: cannot connect\n" );
        return - 1;
    }

    write( sockfd, &ch, 1 );
    read( sockfd, &ch, 1 );
    printf( "response from server: %c\n", ch );
    close( sockfd );

    return 0;
}
::::::::::::::
Server.c
::::::::::::::
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <stdlib.h>

/**
* $Id: select.html,v 1.1 2009/06/22 16:12:25 kishi Exp kishi $
*/

int main( int argc, char** argv ) {

    int server_sockfd, client_sockfd;
    int server_len, client_len;
    struct sockaddr_in server_address;
    struct sockaddr_in client_address;
    int result;
    fd_set readfds, testfds;
    int portNumber;

    if ( argc != 2 ) {
        fprintf( stderr, "Usage: %s [portNumber]\n", argv[ 0 ] );
        return 1;
    }
    portNumber = atoi( argv[ 1 ] );

    /** create server socket */
    bzero ( ( char * ) & server_address, sizeof ( server_address ) );
    server_sockfd = socket( AF_INET, SOCK_STREAM, 0 );
    server_address.sin_family = AF_INET;
    server_address.sin_addr.s_addr = htonl( INADDR_ANY );
    //-----------------------------------------------------------------
    // htonl() is usually used, but this is cygwin's case
    //-----------------------------------------------------------------
    server_address.sin_port = htons( portNumber );

    server_len = sizeof( server_address );
    bind( server_sockfd, ( struct sockaddr * ) & server_address, server_len );
    printf( "bind...\n" );

    /** create connection queue and initialize */
    listen( server_sockfd, 10 );
    printf( "listen...\n" );
    FD_ZERO( &readfds );
    FD_SET( server_sockfd, &readfds );

    /** wait for client's requests */
    while ( 1 ) {
        char ch;
        int fd;
        int nread;

        testfds = readfds;
        printf( "Server is waiting...\n" );
        result = select( FD_SETSIZE, &testfds, ( fd_set* ) 0, ( fd_set* ) 0, ( struct timeval * ) 0 );
        if ( result < 1 ) {
            perror( "Error!" );
        }

        for ( fd = 0;fd < FD_SETSIZE;fd++ ) {
            if ( FD_ISSET( fd, &testfds ) ) {

                if ( fd == server_sockfd ) {

                    client_sockfd = accept( server_sockfd, ( struct sockaddr* ) & client_address, &client_len );
                    FD_SET( client_sockfd, &readfds );
                    printf( "-- adding client on fd %d\n", client_sockfd );

                } else {

                    ioctl( fd, FIONREAD, &nread );

                    if ( nread == 0 ) {
                        close( fd );
                        FD_CLR( fd, &readfds );
                        printf( "-- removing client on fd %d\n", fd );
                    } else {
                        read( fd, &ch, 1 );

                        printf( "Client's request: %c\n", ch );
			//
                        // emulates doing something at server side 
			//
			sleep( 1 );
                        ch++;

                        write( fd, &ch, 1 );
                    }
                }
            }
        }


    }

    return 0;
}
::::::::::::::
requestor.sh
::::::::::::::
#/bin/sh
PORT=11111

./Server ${PORT} &
sleep 5
for index in `seq 1 50`; do
	./Client ${PORT} &
done


inserted by FC2 system