Find the answer to your Linux question:
Results 1 to 3 of 3
I have this C++ code: Code: int main( int argn, char **arg ) { int port = atoi( arg[ 1 ] ); int sock_listen = socket( AF_INET, SOCK_STREAM, 0 ); ...
Enjoy an ad free experience by logging in. Not a member yet? Register.
  1. #1
    Just Joined!
    Join Date
    May 2005
    Posts
    3

    Simple Socket Server Source Help!


    I have this C++ code:
    Code:
    int main( int argn, char **arg )
    {
     int port = atoi( arg[ 1 ] );
    
     int sock_listen = socket( AF_INET, SOCK_STREAM, 0 );
    
     in_addr addr_any = { INADDR_ANY };
     sockaddr_in srv_addr;
     srv_addr.sin_family = AF_INET;
     srv_addr.sin_port = htons( port );
     srv_addr.sin_addr = addr_any;
    
     // set socket options to reuse address and port again in short time
     int opt = 1;
     setsockopt( sock_listen, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof( opt ) );
    
     // assign address and port to socket
     bind( sock_listen, (const sockaddr * ) &srv_addr, sizeof( srv_addr ) );
    
     listen( sock_listen, 1 );
    
     int sock_client = 0;
    
     // go!
     while ( 1 )
     {
         char buf[ 100 ];
    
         fd_set read_wait_set;
         // set all bits to zero
         FD_ZERO( &read_wait_set );
    
         // wait for stdin
         FD_SET( STDIN_FILENO, &read_wait_set );
    
         // select listen or client socket
         if ( sock_client )
             FD_SET( sock_client, &read_wait_set );
         else
             FD_SET( sock_listen, &read_wait_set );
    
         // wait for selected handles
         if ( select( MAX( sock_client, sock_listen ) + 1,
                              &read_wait_set, 0, 0, 0 &#41; < 0 &#41; break;
    
         // data on stdin?
         if &#40; FD_ISSET&#40; STDIN_FILENO, &read_wait_set &#41; &#41;
         &#123;
             //  read data from stdin
             int l = read&#40; STDIN_FILENO, buf, sizeof&#40; buf &#41; &#41;;
             if &#40; l < 0 &#41;
                 printf&#40; "Unable to read data from stdin." &#41;;
             else
                 printf&#40; "Got %d bytes from stdin.", l &#41;;
    
             // send data to client
             l = write&#40; sock_client, buf, l &#41;;
             if &#40; l < 0 &#41;
                 printf&#40; "Unable send data to client." &#41;;
             else
                 printf&#40; "Sent %d bytes to client.", l &#41;;
         &#125;
    
         // new connection form client?
         else if &#40; FD_ISSET&#40; sock_listen, &read_wait_set &#41; &#41;
         &#123;
             sockaddr_in rsa;
             int rsa_size = sizeof&#40; rsa &#41;;
    
             // accept connection from client
             sock_client = accept&#40; sock_listen, &#40; sockaddr * &#41; &rsa, &#40; socklen_t * &#41; &rsa_size &#41;;
    
             uint lsa = sizeof&#40; srv_addr &#41;;
    
             // get my identification
             getsockname&#40; sock_client, &#40; sockaddr * &#41; &srv_addr, &lsa &#41;;
         
             // get client info
             getpeername&#40; sock_client, &#40; sockaddr * &#41; &srv_addr, &lsa &#41;;
    
             printf&#40; "Peer name&#58; '%s'  port&#58; %d",
                      inet_ntoa&#40; srv_addr.sin_addr &#41;, ntohs&#40; srv_addr.sin_port &#41; &#41;;
    
             printf&#40; "Enter 'quit' to quit server." &#41;;
         &#125;
    
         // data from client?
         else if &#40; FD_ISSET&#40; sock_client, &read_wait_set &#41; &#41;
         &#123;
             // read data from socket
             int l = read&#40; sock_client, buf, sizeof&#40; buf &#41; &#41;;
             if &#40; !l &#41;
             &#123;
                 printf&#40; "Client close socket." &#41;;
                 close&#40; sock_client &#41;;
                 sock_client = 0;
                 break;
             &#125;
             else if &#40; l < 0 &#41;
                 printf&#40; "Unable to read data from socket." &#41;;
             else
                 printf&#40; "Read %d bytes from socket.", l &#41;;
    
             // send all data to stdout
             l = write&#40; STDOUT_FILENO, buf, l &#41;;
    
             // check, if client ask to close connection
             if &#40; !strncasecmp&#40; buf, "close", 5 &#41; &#41;
             &#123;
                printf&#40; "Client sent 'close' request, connection closed." &#41;;
                printf&#40; "Now wait for new client." &#41;;
                 close&#40; sock_client &#41;;
                 sock_client = 0;
             &#125;
         &#125;
    
         // quit request from server or client
         if &#40; !strncasecmp&#40; buf, "quit", 4 &#41; &#41;
         &#123;
             close&#40; sock_client &#41;;
             printf&#40; "Quit request entered... exiting now...\n" &#41;;
             break;
         &#125;
     &#125;
    
     close&#40; sock_listen &#41;;
    
     return 0;
    &#125;
    It is a socket server. It accepts a connection from client and prints on the console a message that client writes. What i need it to do, is accept connections from many clients at once. When a client write something, server prints it and when server write a message, all clients print it.
    So far i have figured that i need to place "int pid = fork()" line after accept() function and let the parent process handle accepting connections and child handle the rest, but i still cant make it right!
    Could you please help me? Thanks for any answer!

  2. #2
    scm
    scm is offline
    Linux Engineer
    Join Date
    Feb 2005
    Posts
    1,044
    So far i have figured that i need to place "int pid = fork()" line after accept() function and let the parent process handle accepting connections and child handle the rest, but i still cant make it right!
    No, you let the child process the accept():
    Code:
        for &#40;;;&#41;                            /* loop for connections */
        &#123;
            if &#40;&#40;t= accept&#40;s, NULL, NULL&#41;&#41; < 0&#41; /* get a connection */
            &#123;
              if &#40;errno == EINTR&#41;           /* EINTR might happen on accept&#40;&#41;, */
                continue;                   /* try again */
              perror&#40;"accept"&#41;;             /* bad */
              exit&#40;1&#41;;
            &#125;
            switch&#40;fork&#40;&#41;&#41; &#123;                /* try to handle connection */
            case -1 &#58;                       /* bad news.  scream and die */
                perror&#40;"fork"&#41;;
                close&#40;s&#41;;
                close&#40;t&#41;;
                exit&#40;1&#41;;
            case 0 &#58;                        /* we're the child, do something */
                close&#40;s&#41;;
                do_something&#40;t&#41;;
                exit&#40;0&#41;;
            default &#58;                       /* we're the parent so look for */
                close&#40;t&#41;;                   /* another connection */
                continue;
            &#125;
        &#125;

  3. #3
    Just Joined!
    Join Date
    Apr 2005
    Location
    Romania
    Posts
    42
    Your queue length of pending client connections is 1; extend it with listen():

    listen(sock_listen, n), where n is number of connections allowed on the incoming queue ( max n = SOMAXCONN ).

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •