UNIX Socket FAQ

A forum for questions and answers about network programming on Linux and all other Unix-like systems

You are not logged in.

#1 2012-11-02 04:08 PM

chandradeo
Member
Registered: 2011-12-10
Posts: 6

handling socket descriptors using select()

Hi all

I have started to use select() for receiving data from two socket descriptors. Here is the problem i am facilg to handle two sd.

//   sd1 and sd2 are created here       

         while(1) 
	     {             
	        FD_ZERO(&input);     
		FD_SET(sd1, &input);  
		FD_SET(sd2, &input);  
		max_fd = (fd2 > fd1 ? fd2 : fd1) + 1;
		 
		timeout.tv_sec = 1;
		timeout.tv_usec = 0;
		 
		n = select(max_fd, &input, NULL, NULL, &timeout);                     
		 
		if (n < 0)
		  perror("select failed");
		else if (n == 0)
                   {
		    puts("There is Not any  Input");                    
                   }
	    else
	     {  
		  if (FD_ISSET(sd1, &input))   
                   {
                   printf(" \n iam in  sd1");              
                   
                   }         
                  		      
		  if (FD_ISSET(sd2, &input))  
		    {  

                     printf(" \n iam in sd2");               
                    }
          
                        
            }
    }


when  input for both sds  are there then it prints the both messages( iam in  sd1 and  iam in sd2). But when when i pull out one input say sd1 the it also it is printing both messages but it should print only one.

What is the problem in the above code plz explain.

Offline

#2 2012-11-02 07:02 PM

RobSeace
Administrator
From: Boston, MA
Registered: 2002-06-12
Posts: 3,839
Website

Re: handling socket descriptors using select()

Offline

#3 2012-11-03 04:16 AM

chandradeo1
Guest

Re: handling socket descriptors using select()

#include <stdio.h>   /* Standard input/output definitions */
#include <string.h>  /* String function definitions */
#include <unistd.h>  /* UNIX standard function definitions */
#include <fcntl.h>   /* File control definitions */
#include <errno.h>   /* Error number definitions */
#include <termios.h> /* POSIX terminal control definitions */
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h> 
#include <stdlib.h> 
#include<time.h>
#include <sys/time.h> 
//#include "lcd_api.h"
#include <sys/time.h>

//structures of LCD pannel
    struct lcd_linedisp displine;
    struct lcd_cursorshift shiftcursor;

char _Lcd_disp_buf[15],_Lcd_disp_buf2[11]; 
int ret,min,sec,hr;
//struct timeval tp;
struct sockaddr_in localSock1,localSock2;
struct ip_mreq group1,group2; 
static int counter =0;
int            n;
int            sd1;
int            sd2;
int i2c_fd, fd_lcd;
unsigned char time_buf[10];
char databuf1[29],databuf2[29];
float fsec1,fsec2,ssec1,ssec2,check1,check2;
char sec_buf[3],min_buf[3],hr_buf[3];
struct timeval timeout; 
fd_set  input;    
char databuf1[29],databuf2[29]; 

//////////////////The main section////////////////////////////

				int main(int argc, char **argv) 
				{
					
					
					int fd1,fd2,i,ret1,ret2,ret3;
				         unsigned char buf[10];
				        pthread_t thread1,thread2,thread3;
				                                         
					/* Opening the node to connect to the driver */
						    // fd_lcd = Open_lcd_node();
						    // LCD_Clear();

					/* Create a datagram socket on which to receive. */

					    sd1 = socket(AF_INET, SOCK_DGRAM, 0);
					    if(sd1 < 0)
					    {
					    perror("Opening datagram socket error");
					    exit(1);
					    }

					    else
					    printf("Opening datagram socket....OK.\n");



					    sd2 = socket(AF_INET, SOCK_DGRAM, 0);
					    if(sd2 < 0)
					    {
					    perror("Opening datagram socket error");
					    exit(1);
					    }

					    else
					    printf("Opening datagram socket....OK.\n");
                                            


					   
					    int reuse = 1;
		 if(setsockopt(sd1, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse)) < 0)
					    {
					    perror("Setting SO_REUSEADDR error");
					    close(sd1);
					    exit(1);
					    }
					    else
					    printf("Setting SO_REUSEADDR...OK.\n");
					    


					    
					   
					    reuse = 1;
	 if(setsockopt(sd2, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse)) < 0)
					    {
					    perror("Setting SO_REUSEADDR error");
					    close(sd2);
					    exit(1);
					    }
					    else
					    printf("Setting SO_REUSEADDR...OK.\n");
					   
                                            /* specified as INADDR_ANY. */

					    memset((char *) &localSock1, 0, sizeof(localSock1));
					    localSock1.sin_family = AF_INET;
					    localSock1.sin_port = htons(4321);
					    localSock1.sin_addr.s_addr = INADDR_ANY;
		  if(bind(sd1, (struct sockaddr*)&localSock1, sizeof(localSock1)))
					    {
					    perror("Binding datagram socket error");
					    close(sd1);
					    exit(1);
					    }

					    else
					    printf("Binding datagram socket...OK.\n");

					     

					    memset((char *) &localSock2, 0, sizeof(localSock2));
					    localSock2.sin_family = AF_INET;
					    localSock2.sin_port = htons(4322);
					    localSock2.sin_addr.s_addr = INADDR_ANY;
					    if(bind(sd2, (struct sockaddr*)&localSock2, sizeof(localSock2)))
					    {
					    perror("Binding datagram socket error");
					    close(sd2);
					    exit(1);
					    }
					    else
					     printf("Binding datagram socket...OK.\n");

					 
                                          /* datagrams are to be received. */

				    group1.imr_multiaddr.s_addr = inet_addr("226.1.1.1");
				    group1.imr_interface.s_addr = inet_addr("10.111.5.122");
				    if(setsockopt(sd1, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&group1, sizeof(group1)) < 0)
				    {
				    perror("Adding multicast group error");
				    close(sd1);
				    exit(1);
				    }
				    else
				    printf("Adding multicast group...OK.\n");

				    
				    group2.imr_multiaddr.s_addr = inet_addr("226.1.1.1");
				    group2.imr_interface.s_addr = inet_addr("10.111.5.122");
				    if(setsockopt(sd2, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&group2, sizeof(group2)) < 0)
				    {
				    perror("Adding multicast group error");
				    close(sd2);
				    exit(1);
				    }
				    else
				    printf("Adding multicast group...OK.\n");




     while(1) 
	{  
                int check=0;
               /* Initialize the input set */
	        FD_ZERO(&input);    // initialise the fd set
		FD_SET(sd1, &input); // add fd1 to the fd set ie input
		FD_SET(sd2, &input); // add fd2 to the fd set 
		//max_fd = (fd2 > fd1 ? fd2 : fd1) + 1;
		 
		timeout.tv_sec = 3;
		timeout.tv_usec = 0;
		 
		//n = select(max_fd, &input, NULL, NULL, &timeout); // Returns the number of descriptors in the set 
                 n = select(FD_SETSIZE, &input, NULL, NULL, &timeout); // Returns the number of descriptors in the set 
       
               
                
		/* See if there was an error */
		if (n < 0)
		  perror("select failed");
		else if (n == 0)
                   {
		    puts("There is Not any serial Input");                    
                   }
	else
	{ 


     
// if there is no data the control will not go to the blocking read statement ie it will not go     inside if condition
		  /* Check if there is any fd in the set input */
		  if (FD_ISSET(sd1, &input))   // check if fd1 is in the set input
                   {	
                    check=check+1;

                  //  printf(" \n iam in thread1");              
                    if(read(sd1, databuf1, 28) < 0)
		    {
		    perror("Reading datagram message error");
		    close(sd1);
		    exit(1);
		    }
		    else
                    {     
                    databuf1[28]='\0';
		    printf(" \n the data received thread1 =%s",databuf1);                          
                      // do processing and display data         
                    }  
                 } 




         // if there is no data the control will not go to the blocking read statement
                  		      
		  if (FD_ISSET(sd2, &input))  // check if fd2 is in the set
		    {  

                   //  printf(" \n iam in thread2");    

                 if(check=0)
                 {
                     if(read(sd2, databuf2, 28) < 0)
		      {
		       perror("Reading datagram message error");
		       close(sd2);
		       exit(1);
		      }
		 
		    else 	     
                    {                         
	             databuf2[28]='\0'; 
		     printf(" \n the data received thread2 =%s",databuf2);	                   
                    }	
                 }
          
                        
		   }      




            

                  
       }//else  of select 

}   //while
                                    
				    return 0;
}

/////////////////////end of main///////////////////////////////////

#4 2012-11-03 03:33 PM

RobSeace
Administrator
From: Boston, MA
Registered: 2002-06-12
Posts: 3,839
Website

Re: handling socket descriptors using select()

Offline

#5 2012-11-27 02:01 PM

Cupakabra
Guest

Re: handling socket descriptors using select()

Hello everyone, please i need help ;)

In my example, i have two clients and two servers. I need to give priority to one of these servers. Other needs to listen and wait if first connection fails.

I cannot make connection with server..

So here's my code, and if someone can help me, i would be very grateful.

Client
______________________________________________________________________________________
______________________________________________________________________________________

#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>

int main()
{
	int sockfd, sockfd2, provera_A = 2, provera_B = 2;
	int bytes_recieved1, bytes_recieved2;
	char send_data[1024], recv_data[1024];
	struct hostent *host;
	struct hostent *host2;
	struct sockaddr_in server_addr;
	struct sockaddr_in server_addr2;

	host = gethostbyname ("10.0.0.51");
	host2 = gethostbyname ("10.10.0.50");

	server_addr.sin_family = AF_UNIX;
	server_addr.sin_port = htons (223);
	server_addr.sin_addr = *((struct in_addr *)host->h_addr);
	bzero(&(server_addr.sin_zero),8);

	sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
	if (sockfd<0)
	{
		perror("Opening socket1 error.");
		exit(1);

	}
	else printf("Opening socket1... \n");


	server_addr2.sin_family = AF_UNIX;
	server_addr2.sin_port = htons (224);
	server_addr2.sin_addr = *((struct in_addr *)host2->h_addr);
	bzero(&(server_addr2.sin_zero),8);

	sockfd2 = socket(AF_UNIX, SOCK_STREAM, 0);
	if (sockfd2<0)
	{
		perror("Opening socket2 error");
		exit(1);

	}
	else printf("Opening socket2... \n");

	connect(sockfd, (struct sockaddr *) &server_addr, sizeof(struct sockaddr));
	connect(sockfd2, (struct sockaddr *) &server_addr2, sizeof(struct sockaddr));


	if (connect(sockfd, (struct sockaddr *) &server_addr, sizeof(struct sockaddr)) == -1)
	{
		provera_A = 1;
		printf(" Connection fail - klijent1 \n");

	}

	if (connect(sockfd2, (struct sockaddr *) &server_addr2, sizeof(struct sockaddr)) == -1)
	{
		provera_B = 1;
		printf("Connection fail - klijent2 \n");

	}


	while (provera_A == 2 || provera_B == 2)
	{
         if(provera_A == 2)
         {
        	 bytes_recieved1=recv(sockfd, recv_data, 1024,0);
        	 recv_data[bytes_recieved1] = '\0';

        	 if (strcmp(recv_data, "q") == 0 || strcmp (recv_data, "Q") == 0)
        	 {
        		 close(sockfd);
        		 break;
        	 }else
        		 printf("\nRecieved data on client 1 = %s", recv_data);

        	 printf("\nPritisni (q ili Q za kraj ) - klijent: ");
		 	 gets(send_data);

		 	 if (strcmp(send_data, "q") != 0 && strcmp(send_data, "Q") !=0)
			 send(sockfd, send_data, strlen(send_data), 0);
		 	 else
		 	 {
		 		 send(sockfd, send_data, strlen(send_data), 0);
		 		 close(sockfd);
		 		 break;
		 	 }
         }

         if (provera_A == 1 && provera_B == 2)
         {
        	 bytes_recieved2=recv(sockfd2, recv_data, 1024,0);
        	 recv_data[bytes_recieved2] = '\0';

        	 if (strcmp(recv_data, "q") == 0 || strcmp (recv_data, "Q") == 0)
        	 {
        		 	 close(sockfd2);
		 		 	 exit(1);
        	 }else
        		 printf("\nRecieved data on client 2 = %s", recv_data);

        	 printf("\nPritisni (q ili Q za kraj) - klijent: ");
        	 gets(send_data);

        	 if (strcmp(send_data, "q") != 0 && strcmp(send_data, "Q") !=0)
        		 send(sockfd2, send_data, strlen(send_data), 0);
        	 else
        	 {
        		 send(sockfd2, send_data, strlen(send_data), 0);
        		 close(sockfd2);
        		 break;
        	 }

         }


	 	 if (connect(sockfd, (struct sockaddr *) &server_addr, sizeof(struct sockaddr)) == -1)
	 	 {
	 		 provera_A = 1;
	 	 }

	 	 if (connect(sockfd2, (struct sockaddr *) &server_addr2, sizeof(struct sockaddr)) == -1)
	 	 {
	 		 provera_B = 1;
	 	 }

	}
	 close(sockfd);
	 close(sockfd2);

return 0;
}

________________________________________________________________________________________
________________________________________________________________________________________


Server
________________________________________________________________________________________
________________________________________________________________________________________

#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/un.h>
#include <stdio.h>
#include <unistd.h>
#include <arpa/inet.h>


#define MYPORT 223
#define MY_IP "10.0.0.34"
#define MY_IP2 "10.0.0.33"
#define BACKLOG 20

int main ()
{
	int sockfd, sockfd2, connected, connected2;
	int sin_size, bytes_recieved1, bytes_recieved2;
	char send_data [1024], recv_data[1024];
	struct sockaddr_in my_addr;
	struct sockaddr_in my_addr2;
	struct sockaddr_in their_addr;
	struct sockaddr_in their_addr2;

	sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
	my_addr.sin_family = AF_UNIX;
	my_addr.sin_port = htons (MYPORT);
 	my_addr.sin_addr.s_addr = inet_addr(MY_IP);
	memset(&(my_addr.sin_zero), '\0', 8);

	sockfd2 = socket(AF_UNIX, SOCK_STREAM, 0);
	my_addr2.sin_family = AF_UNIX;
	my_addr2.sin_port = htons (MYPORT);
	my_addr2.sin_addr.s_addr = inet_addr(MY_IP2);
	memset(&(my_addr2.sin_zero), '\0', 8);


	if (bind(sockfd, (struct sockaddr *) &my_addr, sizeof(struct sockaddr)) == -1)
	{
		    printf("bind1");
            perror("Enable to bind");
            exit(1);
    }

	if (bind(sockfd2, (struct sockaddr *) &my_addr2, sizeof(struct sockaddr)) == -1)
	{
		    printf("bind2");
	        perror("Enable to bind");
	       exit(1);
    }

	listen(sockfd, BACKLOG);
	listen(sockfd2, BACKLOG);

	while(1)
	{
		sin_size = sizeof(struct sockaddr_in);
		connected = accept(sockfd, (struct sockaddr *) &their_addr, &sin_size);
		connected2 = accept(sockfd2, (struct sockaddr *) &their_addr2, &sin_size);

		printf("\n Konektovao sam se sa klijentom ");/*, (inet_ntoa(their_addr.sin_addr)
		, ntohs(their_addr.sin_port));*/

		printf("\n Konektovao sam se sa klijentom 2 ");/* (inet_ntoa(their_addr2.sin_addr)
		, ntohs(their_addr2.sin_port));*/

		while(1)
		{

			printf("\n Pritisni (q ili Q za kraj) - server:");
			gets (send_data);

			if(strcmp(send_data, "q") == 0 || strcmp(send_data, "Q") == 0)
			{
				send (connected, send_data, strlen(send_data), 0);
				close(connected);
				break;
			}
			else send(connected, send_data, strlen(send_data),0);

			bytes_recieved1 = recv(connected, recv_data,1024,0);

			recv_data[bytes_recieved1] = '\0';

			if((strcmp(recv_data, "q") == 0) || strcmp(recv_data, "Q")==0)
			{
				close(connected);
				break;
			}

			else
				printf("\n Primljeni podaci na serveru 1 = %s", recv_data);
			//fflush(stdout);

	 	}
		while(1)
		{
		printf("\n Pritisni (q ili Q za kraj) - server:2");
				gets (send_data);

				if(strcmp(send_data, "q") == 0 || strcmp(send_data, "Q") == 0)
				{
					send (connected2, send_data, strlen(send_data), 0);
					close(connected2);
					break;
				}
				else send(connected2, send_data, strlen(send_data),0);

				bytes_recieved2 = recv(connected2, recv_data,1024,0);

				recv_data[bytes_recieved2] = '\0';

				if((strcmp(recv_data, "q") == 0) || strcmp(recv_data, "Q")==0)
				{
					close(connected2);
					break;
				}

				else
					printf("\n Primljeni podaci na serveru 2 = %s", recv_data);
				//fflush(stdout);
		}
	}
	close(sockfd);
	close(sockfd2);
	return 0;
}

__________________________________________________________________________________
__________________________________________________________________________________

#6 2012-11-27 09:31 PM

RobSeace
Administrator
From: Boston, MA
Registered: 2002-06-12
Posts: 3,839
Website

Re: handling socket descriptors using select()

There are many problems with that code...  Let's start with the most glaring: you're using AF_UNIX sockets, but trying to use sockaddr_in structs to represent their addresses...  Unix domain sockets require sockaddr_un structs...  You can only use sockaddr_in with AF_INET sockets...  And, you'll find one of the differences between the two is that sockaddr_un doesn't have a field for a port number; instead, they have a field for a socket name, which is typically the name of a socket file within your local filesystem...  (However, on Linux at least, you can use an arbitrary abstract name that doesn't exist in the filesystem instead by setting the first byte of sun_path to '\0' and then the rest of the name to whatever arbitrary abstract name you wish to use to identify your socket...)  But, I'm not sure you really want to be using Unix domain sockets, anyway...  Given that you reference a pair of 10.* IPs and a pair of port numbers that you seem to be trying to connect to, I suspect you might really want to just be using AF_INET sockets, in which case your current code need merely replace all occurances of "AF_UNIX" with "AF_INET"...

Your client code also first does a connect() on each socket, without checking the return value at all, and THEN does another pair of connect()'s, this time checking the return value, and THEN at the bottom of your while() loop, you're doing another pair of connect()'s each and every time through the loop!  You can only perform a connect() on a socket ONCE...  So, all of those connect() calls after the initial pair are guaranteed to always fail, even if the first two succeeded!

Offline

#7 2012-11-28 08:34 AM

Cupakabra
Guest

Re: handling socket descriptors using select()

#8 2012-11-28 01:48 PM

RobSeace
Administrator
From: Boston, MA
Registered: 2002-06-12
Posts: 3,839
Website

Re: handling socket descriptors using select()

Offline

#9 2012-11-28 03:44 PM

Cupakabra
Guest

Re: handling socket descriptors using select()

#10 2012-11-28 09:54 PM

RobSeace
Administrator
From: Boston, MA
Registered: 2002-06-12
Posts: 3,839
Website

Re: handling socket descriptors using select()

for (;;) {
    sockfd = socket (AF_INET, SOCK_STREAM, 0);
    if (connect (sockfd, &server1, sizeof (server1))) {
        close (sockfd);
        sockfd = socket (AF_INET, SOCK_STREAM, 0);
        if (connect (sockfd, &server2, sizeof (server2))) {
            fprintf (stderr, "Unable to connect to either server!\n");
            exit (-1);
        }
    }

/* send() and recv() on sockfd */

    close (sockfd);
}

Offline

#11 2012-11-28 09:58 PM

RobSeace
Administrator
From: Boston, MA
Registered: 2002-06-12
Posts: 3,839
Website

Re: handling socket descriptors using select()

Offline

#12 2012-11-30 08:11 AM

Cupakabra
Guest

Re: handling socket descriptors using select()

Board footer

Powered by FluxBB