Thread: Socket: Client question

  1. #1
    Registered User
    Join Date
    Jan 2012
    Posts
    37

    Socket: Client question

    Hello,

    I am trying to write a client code in C. What I would like to do is create like an Instant message server-client socket. Where I want to have one Server and multiple Clients. I come to a problem that the client may not handle this, but this cannot be true since we do have instant message. I say this because the flow chart of the Socket Server-Client shows that data needs to be send first then receive (google Image: "socket server and client" the attachment on this site does not work).

    So I present the problem what if you have 1 Server and 3 Clients.

    If one Client writes/sends (lets say "Hello"), then how would the other two Clients receive/read that data (saying "Hello) if Clients writes/sends first. Unless the server is involve with this problem. I hope that makes sense.

    I have posted the server code if the server is the problem.

    Thanks for your time

    Code:
    /* This is a server. This code allows multiple client
    to connect with the same server's port. 
    Non-Blocking I/O and select(); 
    
    
    Step 1: Setup Address structure
    Step 2: Create a socket
    Step 3: Bind the socket to the port
    Step 4: Listen to the socket
    Step 5: Setup an infinite loop to make connections
    
    
    IBM
    http://publib.boulder.ibm.com/infocenter/iseries/v5r3/
    index.jsp?topic=%2Frzab6%2Frzab6xnonblock.htm   
    */
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <sys/types.h> 
    #include <sys/socket.h>
    #include <netinet/in.h>
    
    
    #include <arpa/inet.h>
    #include <netdb.h>
    
    
    #define MAX_CLIENTS 20
    
    
    void error(const char *msg)
    {
        perror(msg);
        exit(1);
    }
    
    
    int main(int argc, char *argv[])
    {
        fd_set master;    //file descriptor master list
        fd_set read_fds;  //file descriptor temp list for select()
        int fdmax;        //file descriptor maximum number
    
    
        int sockfd, newsockfd, portno;//socket, accept, port number
        socklen_t clilen;
        char buffer[256];//for recv and send of data
        int yes=1; //for setsockopt
        struct sockaddr_in serv_addr, cli_addr;
             struct client{                          //struct used to store client information
              char name[32];                     //contains the client name
              int  fd;                           //contains the client file descriptor
             };
             struct client database[MAX_CLIENTS];    //database of client information
             memset(&database, 0, sizeof database);
             int numClients = 0;                     //keep track of how many clients are connected
        int i, j; //loop counters
        int nbytes; //data recv from the client
        char remoteIP[INET6_ADDRSTRLEN + 1];
    
    
        FD_ZERO(&master);    // clear the master and temp sets
        FD_ZERO(&read_fds);
    
    
        //Check if port is given
        if (argc < 2) {
            fprintf(stderr,"ERROR, no port provided\n");
            exit(1);
        }
    
    
        //Step 1: Setup Address structure
        bzero((char *) &serv_addr, sizeof(serv_addr));
        portno = atoi(argv[1]);
        serv_addr.sin_family = AF_INET;
        serv_addr.sin_addr.s_addr = INADDR_ANY;
        serv_addr.sin_port = htons(portno);
    
    
    
    
        //Step 2: Create a socket
        sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if (sockfd < 0){
            error("ERROR opening socket");
        }
        printf("The sockfd1 value is: %d\n", sockfd);
            
        //reuse port if it was still in use
        if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,
                &yes,sizeof(int)) == -1) {
            error("setsockopt");
            exit(1);
        }
    
    
        //Step 3: Bind the socket to the port
        if (bind(sockfd, (struct sockaddr *) &serv_addr,
                sizeof(serv_addr)) < 0){
            close(sockfd);
        }
    
    
    
    
        //Step 4:Listen to the socket
        if (listen(sockfd,10) == -1){
            error("ERROR on listen");
            exit(3);
        }
    
    
        //add file descriptor to master set list
        FD_SET(sockfd, &master);
        fdmax = sockfd; //as of now, the biggest fd is listener
        printf("The fdmax value is: %d\n", fdmax);
             printf("Waiting for Client connections...\n");
             usleep(1000);    
        //main while loop: LOOP and check for connection requests, recieved messages
        while(1) {
            read_fds = master; //copy master list to temp list
    
    
            //Check to see if the select call failed.
            if (select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1) {
                perror("select");
                exit(4);
            }
            //printf("We are at before the main for loop");
            printf("The sockfd2 value is: %d\n", sockfd);
            
            //Step 5: Setup an infinite loop to make connections
            for(i = 0; i <= fdmax; i++) {
                //Check to see if this descriptor is ready
                if (FD_ISSET(i, &read_fds)) { //Check if FD is set
                    //Check to see if this is the listening socket 
                    if (i == sockfd) {//the fd is the listener port [a client is attempting to connect()]
                        //handle new connections
                        clilen = sizeof(cli_addr);
                        newsockfd = accept(sockfd, 
                                (struct sockaddr *) &cli_addr, 
                                &clilen);
                        printf("The newsockfd value is: %d\n", newsockfd);
                        if (newsockfd < 0) 
                            error("ERROR on accept");
                        else {//accept successful
                            //Add the new incoming connection to the master read set                          
                            FD_SET(newsockfd, &master); //add fd to master list
                            if (newsockfd > fdmax) {    //keep tracks of the FD max
                                fdmax = newsockfd;
                                                   database[numClients].fd = newsockfd; //add connection to array
                                                   numClients++; //increment # of client connections
                                                   printf("New Connection Accepted - Total Connections: %d\n", numClients);
                            }
                            printf("selectserver: new connection from %s on "
                                    "socket %d\n",
                                    inet_ntop(AF_INET, &(cli_addr.sin_addr),
                                    remoteIP, sizeof(remoteIP)),
                                    newsockfd);
                        }
                    } else {//not from listener port, must be data from client
                        // handle data from a client
                        printf("  Descriptor %d is readable\n", i);
                        if ((nbytes = recv(i, buffer, sizeof buffer, 0)) <= 0) {
                            //Checks if any client(s) closed
                            if (nbytes == 0) {//conection closed
                                printf("Alert: socket %d hung up\n", i);
                            } else {
                                error("recv");
                            }
                            close(i); //close sockfd that leaves!
                            FD_CLR(i, &master); //remove that client from master set
                        } else {
                            //we got some data from a client
                            for(j = 0; j <= fdmax; j++) {
                                //send to data every client 
                                if (FD_ISSET(j, &master)) {
                                    //except the client that sent the data
                                    if (j != sockfd && j != i) {
                                        if (send(j, buffer, nbytes, 0) == -1) {
                                            error("send");
                                        }
                                    }
                                }
                            }
                        }
                    } // End handle data from client
                } // End got new incoming connection
            } // End flag set by a file descriptors
        } // End of main while Loop
    
    
        return 0;
    
    
    }//End of main


  2. #2
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    You don't have to send data before you receive data.
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  3. #3
    Registered User
    Join Date
    Mar 2011
    Posts
    546
    your question isn't clear. but on the client side, it doesn't matter if you have multiple clients or one client. each client operates separately and has a point to point connection to the server. so as far as the clients are concerned, there is only the server and whatever the server sends. are you asking how the client can get keyboard input in parallel with receiving messages from the server? if so, it depends on the operating system. on Linux/Unix you could do it with a single select that is monitoring the keyboard and the socket. on windows you need to do something different, maybe with a keyboard input thread that sends to the server, and a separate socket receiving thread that receives messages from the server. then it depends on your user interface how you display what you input and what you receive.

  4. #4
    Registered User
    Join Date
    Jan 2012
    Posts
    37
    dmh2000,

    If you do not mind if I could give an example what I am trying to understand. All I want is a multiple instant message where if one guy sends a message everyone gets that message..

    Lets say we have three people Instant messaging.

    person1 sends "Hello" on his terminal to the server, then the server sends that message to person2 and person3. Thus person2 and person3's terminal displays "Hello".

    I hope that makes sense.

    If I run a simple client code such as the one below it will wait. I understand that fgets() will make the client wait, but I do not think that will fix the problem.

    Code:
    #include <stdio.h>#include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <netdb.h> 
    
    
    void error(const char *msg)
    {
        perror(msg);
        exit(0);
    }
    
    
    int main(int argc, char *argv[])
    {
        int sockfd, portno, n;
        struct sockaddr_in serv_addr;
        struct hostent *server;
    
    
        char buffer[256];
        if (argc < 3) {
           fprintf(stderr,"usage %s hostname port\n", argv[0]);
           exit(0);
        }
        portno = atoi(argv[2]);
        sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if (sockfd < 0) 
            error("ERROR opening socket");
        server = gethostbyname(argv[1]);
        if (server == NULL) {
            fprintf(stderr,"ERROR, no such host\n");
            exit(0);
        }
        bzero((char *) &serv_addr, sizeof(serv_addr));
        serv_addr.sin_family = AF_INET;
        bcopy((char *)server->h_addr, 
             (char *)&serv_addr.sin_addr.s_addr,
             server->h_length);
        serv_addr.sin_port = htons(portno);
        if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) 
            error("ERROR connecting");
        printf("Please enter the message: ");
    	while(1){//Edited While Loop
    		bzero(buffer,256);
    		fgets(buffer,255,stdin);
    		n = write(sockfd,buffer,strlen(buffer));
    		if (n < 0) 
    			error("ERROR writing to socket");
    		bzero(buffer,256);
    		n = read(sockfd,buffer,255);
    		if (n < 0) 
    			error("ERROR reading from socket");
    		printf("%s\n",buffer);
    	}//Edited: While Loop
        close(sockfd);
        return 0;
    }


    Thanks for your time.

  5. #5
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Moved to Networking/Device Communication.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. (socket) - Client question
    By Annonymous in forum Networking/Device Communication
    Replies: 2
    Last Post: 06-15-2011, 03:21 PM
  2. Socket ( server client Get pid )
    By Syd in forum C Programming
    Replies: 0
    Last Post: 02-15-2011, 08:00 AM
  3. SSH Client Socket
    By shawon in forum Linux Programming
    Replies: 5
    Last Post: 10-28-2009, 04:01 AM
  4. Socket, client (help-me)
    By darkducke in forum C Programming
    Replies: 3
    Last Post: 12-23-2007, 09:38 AM
  5. socket web client
    By Abila in forum C Programming
    Replies: 0
    Last Post: 06-28-2003, 04:42 PM