CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 5 of 5
  1. #1
    Join Date
    Jul 2011
    Posts
    3

    Help on binding two sockets to two ports on ONE server [Socket Programming in UNIX]

    Ok so this is what I have.

    I have a separate code for both server and client.

    Now, what I want to do is, enable the server to listen and accept connections on TWO OR MORE ports [say 5000 and 5340], thus, effectively creating two different "chat rooms". A bunch of clients communicate with each other and the server on the first port [5000], and a different bunch of clients communicate with each other, and the server on the other port [5340].

    I have been able to get the server to listen and communicate on two different ports. But now, when I send a chat message from the client to the server, or from server to client, it doesn't display the message at the same time it receives it. Let me make this more clear. For example, I connect to the server on the first port. I then type two messages on the client, 'Hey' and 'Hurr Durr'. The server doesn't display anything. Now when I type 'Anyone there' on the server, it then displays 'Hey' and 'Hurr Durr' in quick succession. I think it's something to do with my for statements. I've tried to find out what exactly could the problem be for hours, and I'm drawing a blank.

    Here is the server code :

  2. #2
    Join Date
    Jul 2011
    Posts
    3

    Re: Help on binding two sockets to two ports on ONE server [Socket Programming in UNI

    SERVER CODE :
    Code:
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <netdb.h>
    #include <stdio.h>
    #include <unistd.h>  //For read() and write()
    #include <stdlib.h>
    #include <string.h>
    #include <time.h>
    
    #define MSG_SIZE 80
    #define MAX_CLIENTS 100
    #define MYPORT 7400
    
    void exitClient(int fd, fd_set *readfds, char fd_array[], int *num_clients)
       {
          int i;
          close(fd);
          FD_CLR(fd, readfds); //clear the leaving client from the set
          for (i = 0; i < (*num_clients) - 1; i++)
              {
                 if (fd_array[i] == fd)
                     {
                         break;
                     } 
              }           
          for (; i < (*num_clients) - 1; i++)
              {
                  (fd_array[i]) = (fd_array[i + 1]);
              }
          (*num_clients)--;
       }
    
    int main(int argc, char *argv[]) 
      {
         int i=0;
         int port1, port2;
         int num_clients1 = 0, num_clients2 = 0;
         int server_sockfd1,server_sockfd2, client_sockfd1, client_sockfd2;
         struct sockaddr_in chatroom1, chatroom2;
         int addresslen = sizeof(struct sockaddr_in);
         int fd;
         char fd_array1[MAX_CLIENTS], fd_array2[MAX_CLIENTS];
         fd_set readfds1, readfds2, testfds1, testfds2, clientfds, readfds;
         char msg[MSG_SIZE + 1];
         char kb_msg[MSG_SIZE + 10];
    
    
         int sockfd;
         int result;
         char hostname[MSG_SIZE];
         struct hostent *hostinfo;
         struct sockaddr_in address;
         char alias[MSG_SIZE];
         int clientid;
    
        
                 printf("\n*** Server program. (enter \"quit\" to close): \n");
                 fflush(stdout);
                 printf("Enter the two ports :");
                 scanf("&#37;d %d",&port1,&port2);
    
         /* Create and name a socket for the server */
                 server_sockfd1 = socket(AF_INET, SOCK_STREAM, 0);
                 chatroom1.sin_family = AF_INET;
                 chatroom1.sin_addr.s_addr = htonl(INADDR_ANY);
                 chatroom1.sin_port = htons(port1);
                 bind(server_sockfd1, (struct sockaddr *)&chatroom1, addresslen);
    
    
                 server_sockfd2 = socket(AF_INET, SOCK_STREAM, 0);
                 chatroom2.sin_family = AF_INET;
                 chatroom2.sin_addr.s_addr = htonl(INADDR_ANY);
                 chatroom2.sin_port = htons(port2);
                 bind(server_sockfd2, (struct sockaddr *)&chatroom2, addresslen);
    
         /* Create a connection queue and initialize a file descriptor set */
                 listen(server_sockfd1, 1);
                 listen(server_sockfd2, 1);
    
    
                 FD_ZERO(&readfds1);
                 FD_ZERO(&readfds2);
                 FD_SET(server_sockfd1, &readfds1);
                 FD_SET(server_sockfd2, &readfds2);
                 FD_SET(0, &readfds1); /* Add keyboard to file descriptor set */
                 FD_SET(0, &readfds2); /* Add keyboard to file descriptor set */
         
              
    
    
         /* Now wait for clients and requests */
                 while (1)
                     {
                         testfds1 = readfds1;
                         select(FD_SETSIZE, &testfds1, NULL, NULL, NULL);
    
                         testfds2 = readfds2;
                         select(FD_SETSIZE, &testfds2, NULL, NULL, NULL);
    
                                             
            /* If there is activity, find which descriptor it's on using FD_ISSET */
                         for (fd = 0; fd < FD_SETSIZE; fd++)
                             {
                                 if (FD_ISSET(fd, &testfds1)||FD_ISSET(fd, &testfds2)) 
                                     {
                                         if (fd == server_sockfd1) 
                                             { /* Accept a new connection request */
                                                 client_sockfd1 = accept(server_sockfd1, NULL, NULL);
                                                 if (num_clients1 < MAX_CLIENTS) 
                                                     {
                                                         FD_SET(client_sockfd1, &readfds1);
                                                         fd_array1[num_clients1]=client_sockfd1;
                                                         /*Client ID*/
                                                         printf("Client %d joined\n",num_clients1++);
                                                         fflush(stdout);
                                                         sprintf(msg,"M%2d",client_sockfd1);
                                                         /*write 2 byte clientID */
                                                         send(client_sockfd1,msg,strlen(msg),0);
                                                     }
                                                 else 
                                                     {
                                                         sprintf(msg, "XSorry, too many clients. Try again later.\n");
                                                         write(client_sockfd1, msg, strlen(msg));
                                                         close(client_sockfd1);
                                                     }
                                             }
    
    
                                         else if (fd == server_sockfd2) 
                                             { /* Accept a new connection request */
                                                 client_sockfd2 = accept(server_sockfd2, NULL, NULL);
                                                 if (num_clients2 < MAX_CLIENTS) 
                                                     {
                                                         FD_SET(client_sockfd2, &readfds2);
                                                         fd_array2[num_clients2]=client_sockfd2;
                                                         /*Client ID*/
                                                         printf("Client %d joined\n",num_clients2++);
                                                         fflush(stdout);
                                                         sprintf(msg,"M%2d",client_sockfd2);
                                                         /*write 2 byte clientID */
                                                         send(client_sockfd2,msg,strlen(msg),0);
                                                     }
                                                 else 
                                                     {
                                                         sprintf(msg, "XSorry, too many clients. Try again later.\n");
                                                         write(client_sockfd2, msg, strlen(msg));
                                                         close(client_sockfd2);
                                                     }
                                             }
    
    
                                   
                                         else if (fd == 0) 
                                             { /* Process keyboard activity */
                                                 fgets(kb_msg, MSG_SIZE + 1, stdin);
                                                 if (strcmp(kb_msg, "quit\n")==0) 
                                                     {
                                                         sprintf(msg, "XServer is shutting down.\n");
                                                         for (i = 0; i < num_clients1 ; i++) 
                                                             {
                                                                 write(fd_array1[i], msg, strlen(msg));
                                                                 close(fd_array1[i]);
                                                             }
                                                         for (i = 0; i < num_clients2 ; i++) 
                                                             {
                                                                 write(fd_array2[i], msg, strlen(msg));
                                                                 close(fd_array2[i]);
                                                             }
                                                         close(server_sockfd1);
                                                         close(server_sockfd2);
                                                         exit(0);
                                                     }
                                                 else 
                                                     {
                                                         sprintf(msg, "M%s", kb_msg);
                                                         for (i = 0; i < num_clients1 ; i++)
                                                             {
                                                                 write(fd_array1[i], msg, strlen(msg));
                                                             }    
                                                         for (i = 0; i < num_clients2 ; i++)
                                                             {
                                                                 write(fd_array2[i], msg, strlen(msg));
                                                             }                     
                                                     } 
                                             }
                                         else if(FD_ISSET(fd, &testfds1)) 
                                             { /*Process Client specific activity*/
                                               //read data from open socket
                                               result = read(fd, msg, MSG_SIZE);
                                               if(result==-1)
                                                    {
                                                        perror("read()");
                                                    }    
                                               else if(result>0)
                                                   {
                                                       /*read 2 bytes client id*/
                                                       sprintf(kb_msg,"M%2d",fd);
                                                       msg[result]='\0';
                                                       /*concatinate the client id with the client's message*/
                                                       strcat(kb_msg,msg+1);
                                                       /*print to other clients*/
                                                       for(i=0;i<num_clients1;i++)
                                                           {
                                                              if (fd_array1[i]!= fd) /*dont write msg to same client*/
                                                              write(fd_array1[i],kb_msg,strlen(kb_msg));
                                                           }
                                                       /*print to server*/
                                                       printf("%s",kb_msg+1);
                                                       /*Exit Client*/
                                                       if(msg[0] == 'X')
                                                           {
                                                               exitClient(fd,&readfds1, fd_array1,&num_clients1);
                                                           }
                                                   }
                                             }
    
                                         else if(FD_ISSET(fd, &testfds2)) 
                                             { /*Process Client specific activity*/
                                               //read data from open socket
                                               result = read(fd, msg, MSG_SIZE);
                                               if(result==-1)
                                                    {
                                                        perror("read()");
                                                    }    
                                               else if(result>0)
                                                   {
                                                       /*read 2 bytes client id*/
                                                       sprintf(kb_msg,"M%2d",fd);
                                                       msg[result]='\0';
                                                       /*concatinate the client id with the client's message*/
                                                       strcat(kb_msg,msg+1);
                                                       /*print to other clients*/
                                                       for(i=0;i<num_clients2;i++)
                                                           {
                                                              if (fd_array2[i]!= fd) /*dont write msg to same client*/
                                                              write(fd_array2[i],kb_msg,strlen(kb_msg));
                                                           }
                                                       /*print to server*/
                                                       printf("%s",kb_msg+1);
                                                       /*Exit Client*/
                                                       if(msg[0] == 'X')
                                                           {
                                                               exitClient(fd,&readfds2, fd_array2,&num_clients2);
                                                           }
                                                   }
                                             }
    
                                 else if(!FD_ISSET(fd, &testfds1) && !FD_ISSET(fd, &testfds2))
                                     {
                                         /* A client is leaving */                     
                                         exitClient(fd,&readfds1, fd_array1,&num_clients1);
                                     }//if
                                  }//if
                             }//for
    
    
                     }//while
             
      }//main


    And this is client code :

    Code:
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <netdb.h>
    #include <stdio.h>
    #include <unistd.h>  //For read() and write()
    #include <stdlib.h>
    #include <string.h>
    #include <time.h>
    
    #define MSG_SIZE 80
    #define MAX_CLIENTS 100
    #define MYPORT 7400
    
    
    int main(int argc, char *argv[]) 
    {
      int port;
      int num_clients = 0;
      int fd;
      fd_set readfds, testfds, clientfds;
      char msg[MSG_SIZE + 1];
      char kybd_msg[MSG_SIZE + 10];
      int sockfd;
      int result;
      char hostname[MSG_SIZE];
      struct hostent *hostinfo, *hp;
      struct sockaddr_in address;
      int clientid;
      int auth;
      int i;
      char clientname[100];
      size_t size;
      time_t now;
      struct tm *tm;
      int newport;
      char cmd[100];
      
      
      printf("*** Client applet. (type |-quit-| to close): \n");
      printf("\nPlease enter the port to connect to : ");
      scanf("%i",&port);
      printf("Please enter the address of the host to connect to : ");
      scanf("%s",&hostname);
      printf("\n");
      fflush(stdout);
       
          /* Create a socket for the client */
          sockfd = socket(AF_INET, SOCK_STREAM, 0);
    
          /* Name the socket, as agreed with the server */
          hostinfo = gethostbyname(hostname); /* look for host's name */
          address.sin_addr = *(struct in_addr *)*hostinfo -> h_addr_list;
          address.sin_family = AF_INET;
          address.sin_port = htons(port);
    
          /* Connect the socket to the server's socket */
          if(connect(sockfd, (struct sockaddr *)&address, 
    						sizeof(address)) < 0)
            {
              perror("Error in connecting.");
              exit(1);
            }
          fflush(stdout);
          FD_ZERO(&clientfds);
          FD_SET(sockfd,&clientfds);
          FD_SET(0,&clientfds);//stdin
          
          printf("\nPlease enter your chat messages below.\n");	
         
          /* Now wait for messages from the server */
          while (1)
            {
              testfds=clientfds;
              select(FD_SETSIZE,&testfds,NULL,NULL,NULL);
              for(fd=0;fd<FD_SETSIZE;fd++)
                {
                  if(FD_ISSET(fd,&testfds))
                    {
                       if(fd == sockfd)
                         {  /*Accept data from open socket */
                            result = read(sockfd, msg, MSG_SIZE); 
                            msg[result] = '\0';
                            now=time(NULL);
                            tm=localtime(&now);
                            printf("%d:%d : %s",tm->tm_hour,tm->tm_min,msg +1);
                            if (msg[0] == 'X') 
                              {
                                close(sockfd);
                                exit(0);
                              }
                         }
                       else if(fd == 0)
                        { /*process keyboard activiy*/
                          fgets(kybd_msg, MSG_SIZE+1, stdin);
                          if(strcmp(kybd_msg, "quit\n")==0)
                            {
    		          sprintf(msg, "X Client is shutting down.\n");
                              write(sockfd, msg, strlen(msg));
                              close(sockfd); //close current client
                              exit(0); //end program
                            }
                          else 
                            {
                              sprintf(msg, "M %s", kybd_msg);
                              write(sockfd, msg, strlen(msg));
                            }
                        }//elseif
                    }//if
                }//for
            }//while
    }//main

  3. #3
    Join Date
    May 2001
    Location
    Germany
    Posts
    1,158

    Re: Help on binding two sockets to two ports on ONE server [Socket Programming in UNI

    One problem might be your use of the select() calls.
    Code:
    testfds1 = readfds1;
    select(FD_SETSIZE, &testfds1, NULL, NULL, NULL);
    
    testfds2 = readfds2;
    select(FD_SETSIZE, &testfds2, NULL, NULL, NULL);
    When the first call returns, there might be some action on one of the socket in testfds1, but that isn't processed before the second call, which is now entered, returns. Now both FD sets can be evaluated.
    I'd put all current sockets into one FD and remember the position, where the sockets for the chatroom 2 begin. That would give you one call to select. Maybe then your problem can be reduced, if not solved.

    HTH,
    Richard

  4. #4
    Join Date
    Jul 2011
    Posts
    3

    Re: Help on binding two sockets to two ports on ONE server [Socket Programming in UNI

    Hmm, how exactly would i specify where to start the fd's for the second socket in the FD_SET?

  5. #5
    Join Date
    May 2001
    Location
    Germany
    Posts
    1,158

    Re: Help on binding two sockets to two ports on ONE server [Socket Programming in UNI

    Well, if you set 5 sockets for chatroom 1 via FD_SET, then you know that in
    Code:
     for (fd = 0; fd < FD_SETSIZE; fd++)
    when to switch from chatroom 1 to 2, don't you?

Tags for this Thread

Posting Permissions

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





Click Here to Expand Forum to Full Width

Featured