Socket Prgm

Embed Size (px)

Citation preview

  • 8/10/2019 Socket Prgm

    1/5

    /** Handle multiple socket connections with select and fd_set on Linux

    Silver Moon ( [email protected])*/#include

    #include //strlen#include #include #include //close#include //close#include #include #include #include //FD_SET, FD_ISSET, FD_ZERO macros#define TRUE 1#define FALSE 0

    #define PORT 8888int main(int argc , char *argv[]){ int opt = TRUE; int master_socket , addrlen , new_socket , client_socket[30] , max_clients =30 , activity, i , valread , sd; int max_sd; struct sockaddr_in address;

    char buffer[1025]; //data buffer of 1K

    //set of socket descriptors

    fd_set readfds;

    //a message char *message = "ECHO Daemon v1.0 \r\n";

    //initialise all client_socket[] to 0 so not checked for (i = 0; i < max_clients; i++)

    { client_socket[i] = 0; }

    //create a master socket

    if( (master_socket = socket(AF_INET , SOCK_STREAM , 0)) == 0){ perror("socket failed"); exit(EXIT_FAILURE); }

    //set master socket to allow multiple connections , this is just a good habit, it will work without this if( setsockopt(master_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt)) < 0 ) { perror("setsockopt"); exit(EXIT_FAILURE);

    }

    //type of socket created

  • 8/10/2019 Socket Prgm

    2/5

    address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = htons( PORT );

    //bind the socket to localhost port 8888 if (bind(master_socket, (struct sockaddr *)&address, sizeof(address)) 0) FD_SET( sd , &readfds);

    //highest file descriptor number, need it for the select function if(sd > max_sd) max_sd = sd; }

    //wait for an activity on one of the sockets , timeout is NULL , so waitindefinitely activity = select( max_sd + 1 , &readfds , NULL , NULL , NULL);

    if ((activity < 0) && (errno!=EINTR)){

    printf("select error"); }

    //If something happened on the master socket , then its an incoming conn

    ection if (FD_ISSET(master_socket, &readfds))

    {

  • 8/10/2019 Socket Prgm

    3/5

    if ((new_socket = accept(master_socket, (struct sockaddr *)&address,(socklen_t*)&addrlen))

  • 8/10/2019 Socket Prgm

    4/5

    a read buffer[valread] = '\0'; send(sd , buffer , strlen(buffer) , 0 ); } } } }

    return 0;

    }

    Compile and run the above program. Then connect to it using telnet from 3 different terminals.

    $ telnet localhost 8888Now whatever you type and send to server will be send back as it is, or echoed.

    The server terminal would show details of connections like this :

    Waiting for connections...New connection , socket fd is 4 , ip is : 127.0.0.1 , port : 57831Welcome message sent successfullyAdding to list of sockets as 0New connection , socket fd is 5 , ip is : 127.0.0.1 , port : 57832Welcome message sent successfullyAdding to list of sockets as 1New connection , socket fd is 6 , ip is : 127.0.0.1 , port : 57833Welcome message sent successfullyAdding to list of sockets as 2

    New connection , socket fd is 7 , ip is : 127.0.0.1 , port : 57834Welcome message sent successfullyThe client terminal can be like this

    $ telnet localhost 8888Trying 127.0.0.1...Connected to localhost.Escape character is '^]'.ECHO Daemon v1.0ccccccddddddffffffThere are other functions that can perform tasks similar to select. pselect , poll , ppoll

    Resources

    1. http://pubs.opengroup.org/onlinepubs/7908799/xsh/select.html2. http://linux.die.net/man/2/select

    1. Is it necessary to reset the fd_set between select system call?

    Ans:Yes (it is necessary to reset the fd_set between select() system calls).

  • 8/10/2019 Socket Prgm

    5/5

    It is a nuisance, but they act as input/output parameters; they are read by andmodified by the system call. When select() returns, the values have all been modified to reflect the set of file descriptors ready. So, every time before you call select(), you have to (re)initialize the fd_set values.