LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Sockets Programming (https://www.linuxquestions.org/questions/programming-9/sockets-programming-830625/)

LeboKG 09-06-2010 12:45 PM

Sockets Programming
 
Hello everyone, please help.

We are trying to create a message forwarder program that receive a message on Port A and pass it on t Port B. Also receive a message from Port C and Pass it on to Port D as follows.

----------------- ----------------- ----------------
| P-A |------> |P-A P-B |------> |P-B |
| Computer X | | Forwarder | | Computer Y |
| P-D |<------ |P-D P-C |<------ |P-C |
----------------- ----------------- ----------------

At the start of our program we setup UDP Sockets with different Port Numbers.
In main() we then use select() to monitor the two receive sockets (P-A and P-C). We test which Socket has received data using FD_ISSET(). Upon reception of a packet, we call the recvfrom() function to read the packet out of that Socket and pass it on to the forwarding Socket which forward it to the relevant computer using sendto().

The problem we have is that Select() only pick up 1 Socket i.e P-A all the time.

Please note: We tried to read each receive Non-blocking Socket in a sequential manner and we still got one socket active.

We suspect it has to do with Ubuntu Linux.We use Ubuntu 9.04. It appears only one receive socket can work at any one time, not multiple receive sockets.Is there any configuration that needs to be done before setting up these sockets?

The Program is listed below.PLEASE HELP.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <fcntl.h>
#include <sys/stat.h>
#define MAXBUFLEN 1500

int a;
int b;
int c;
int d;
int i;
FILE *fp;
int fd;
int Terminate_cmd;
int sockfd_1;
int sockfd_2;
int sockfd_3;
int sockfd_4;
fd_set master;
int fdmax;
struct addrinfo hints_1, *servinfo_1, *p_1;
struct addrinfo hints_2, *servinfo_2, *p_2;
struct addrinfo hints_3, *servinfo_3, *p_3;
struct addrinfo hints_4, *servinfo_4, *p_4;
struct sockaddr_storage their_addr_1;
struct sockaddr_storage their_addr_2;
struct sockaddr_storage their_addr_3;
struct sockaddr_storage their_addr_4;
int rv_1;
int rv_2;
int rv_3;
int rv_4;
int numbytes_1;
int numbytes_2;
int buf_1[MAXBUFLEN];
int buf_2[MAXBUFLEN];
socklen_t addr_len_1;
socklen_t addr_len_2;
char s[INET6_ADDRSTRLEN];
int sendTo_1;
int sendTo_2;
char buffer_1[MAXBUFLEN];
char buffer_2[MAXBUFLEN];
size_t bytes_read_1 = 0;
size_t bytes_read_2 = 0;


void *get_in_addr(struct sockaddr *sa)
{
if (sa->sa_family == AF_INET)
{
return &(((struct sockaddr_in*)sa)->sin_addr);
}
return &(((struct sockaddr_in6*)sa)->sin6_addr);
}

int initialize()
{
//***************************************************************************************************//
//------------------------------------CREATION OF THE FIRST SOCKET-----------------------------------//
//***************************************************************************************************//


printf("DATA PROCESSING UNIT INITIALIZATION......\n");
memset(&hints_1, 0, sizeof hints_1);
hints_1.ai_family = AF_UNSPEC;
hints_1.ai_socktype = SOCK_DGRAM;
hints_1.ai_flags = AI_PASSIVE;
if ((rv_1 = getaddrinfo(NULL, "8000", &hints_1, &servinfo_1)) != 0)
{
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv_1));
return 1;
}
for(p_1 = servinfo_1; p_1 != NULL; p_1 = p_1->ai_next)
{
if ((sockfd_1 = socket(p_1->ai_family, p_1->ai_socktype,p_1->ai_protocol)) == -1)
{
perror("Receiving: socket");
continue;
}
if (bind(sockfd_1, p_1->ai_addr, p_1->ai_addrlen) == -1)
{
close(sockfd_1);
perror("Receiving: bind");
continue;
}
break;
}
if (p_1 == NULL)
{
fprintf(stderr, "Receiving: failed to bind socket\n");
return 2;
}
freeaddrinfo(servinfo_1);
printf("SOCKET no. 8000 successfully created\n");

//***************************************************************************************************//
//------------------------------------CREATION OF THE SECOND SOCKET----------------------------------//
//***************************************************************************************************//

memset(&hints_2, 0, sizeof hints_2);
hints_2.ai_family = AF_UNSPEC;
hints_2.ai_socktype = SOCK_DGRAM;

if ((rv_2 = getaddrinfo("192.168.0.104", "8001", &hints_2, &servinfo_2)) != 0)
{
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv_2));
return 1;
}
for(p_2 = servinfo_2; p_2 != NULL; p_2 = p_2->ai_next)
{
if ((sockfd_2 = socket(p_2->ai_family, p_2->ai_socktype,p_2->ai_protocol)) == -1)
{
perror("Sending: socket");
continue;
}

break;
}
if (p_2 == NULL)
{
fprintf(stderr, "Sending: failed to bind second socket\n");
return 2;
}
printf("SOCKET no. 8001 successfully created\n");
freeaddrinfo(servinfo_2);

//***************************************************************************************************//
//------------------------------------CREATION OF THE THIRD SOCKET-----------------------------------//
//***************************************************************************************************//

memset(&hints_3, 0, sizeof hints_3);
hints_3.ai_family = AF_UNSPEC; // set to AF_INET to force IPv4
hints_3.ai_socktype = SOCK_DGRAM;
hints_3.ai_flags = AI_PASSIVE; // use my IP
if ((rv_3 = getaddrinfo(NULL, "9000", &hints_3, &servinfo_3)) != 0)
{
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv_3));
return 1;
}
for(p_3 = servinfo_3; p_3 != NULL; p_3 = p_3->ai_next)
{
if ((sockfd_3 = socket(p_3->ai_family, p_3->ai_socktype,p_3->ai_protocol)) == -1)
{
perror("listener: socket");
continue;
}
if (bind(sockfd_3, p_3->ai_addr, p_3->ai_addrlen) == -1)
{
close(sockfd_3);
perror("listener: bind");
continue;
}
break;
}
if (p_3 == NULL)
{
fprintf(stderr, "listener: failed to bind socket\n");
return 2;
}
freeaddrinfo(servinfo_3);
printf("SOCKET no. 9000 successfully created\n");

//***************************************************************************************************//
//------------------------------------CREATION OF THE FOURTH SOCKET----------------------------------//
//***************************************************************************************************//

memset(&hints_4, 0, sizeof hints_4);
hints_4.ai_family = AF_UNSPEC;
hints_4.ai_socktype = SOCK_DGRAM;

if ((rv_4 = getaddrinfo("192.168.0.104", "9001", &hints_4, &servinfo_4)) != 0)
{
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv_4));
return 1;
}
for(p_4 = servinfo_4; p_4 != NULL; p_4 = p_4->ai_next)
{
if ((sockfd_4 = socket(p_4->ai_family, p_4->ai_socktype,p_4->ai_protocol)) == -1)
{
perror("listener: socket");
continue;
}
break;
}
if (p_4 == NULL)
{
fprintf(stderr, "listener: failed to bind second socket\n");
return 2;
}
printf("SOCKET no. 9001 successfully created\n");
freeaddrinfo(servinfo_4);
}

void Terminate(void)
{

close(sockfd_1);
close(sockfd_2);
close(sockfd_3);
close(sockfd_4);

for (i=0; i < 1000000; ++i)
{;}
exit(1);
}

void Foward_To_Y()
{
sendTo_1 = sendto(sockfd_2, &buf_1, numbytes_1, 0,p_1->ai_addr, p_1->ai_addrlen);

}

void Forward_To_X()
{

sendTo_2 = sendto(sockfd_4, &buf_2, numbytes_2, 0,p_4->ai_addr, p_4->ai_addrlen);

}

int main(void)
{
initialize();
FD_ZERO(&master);
FD_SET(sockfd_1,&master);
FD_SET(sockfd_3,&master);
fdmax= sockfd_3;
while (1)
{
b = select(fdmax+1, &master,NULL,NULL,NULL);
printf(" The number of Sockets Set is %d \n",b);
Terminate_cmd++;
if (FD_ISSET(sockfd_1,&master))
{
addr_len_1 = sizeof their_addr_1;
numbytes_1 = recvfrom(sockfd_1, buf_1, MAXBUFLEN-1 ,MSG_DONTWAIT,(struct sockaddr *)&their_addr_1, &addr_len_1);
Foward_To_Y();
}
if (FD_ISSET(sockfd_3,&master))
{
addr_len_2 = sizeof their_addr_2;
numbytes_2 = recvfrom(sockfd_3, buf_2, MAXBUFLEN-1 , MSG_DONTWAIT,(struct sockaddr *)&their_addr_2, &addr_len_2);
Forward_To_X();
}
if ( Terminate_cmd == 50)
{
Terminate();
}
}
}

14moose 09-06-2010 01:02 PM

You need to call FD_xxx inside your loop (not just before you start your loop). Look here:

http://publib.boulder.ibm.com/infoce...6xnonblock.htm

Or check out Beej's Guide:
http://beej.us/guide/bgnet/output/ht...ed.html#select

mselaledi 09-06-2010 01:59 PM

I just tried 14moose's suggestion. Moving FD_XXX inside the loop does not change the code.

- Quite a complex one...

LeboKG 09-06-2010 02:40 PM

Could it be by the way we set set-up the socket causing problem. Can someone advice if we setup the 4 UDP sockets properly or not.

14moose 09-08-2010 10:08 AM

Here's how I'd "set up a socket":
Code:

#if defined(WIN32)
  #define SOCKERRNO WSAGetLastError ()
  #define H_ERRNO WSAGetLastError ()
  #define CLOSESOCKET closesocket
  typedef int SOCKLEN_T;
#else
  #define INVALID_SOCKET -1
  #define CLOSESOCKET close
  #define SOCKERRNO errno
  #define H_ERRNO h_errno
  typedef int SOCKET;
  typedef struct sockaddr SOCKADDR, *LPSOCKADDR;
  typedef struct sockaddr_in SOCKADDR_IN, *LPSOCKETADDR_IN;
  typedef struct hostent HOSTENT, *LPHOSTENT;
  typedef struct in_addr IN_ADDR, *LPIN_ADDR;
  typedef socklen_t SOCKLEN_T;
#endif
...
  SOCKET sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
  if (sock == INVALID_SOCKET)
  {
    printf ("ERROR: unable to create socket, errno: %d!\n", SOCKERRNO);
    return -1;
  }

And I believe (strongly believe) the problem is the way you're using "select()"

IMHO .. PSM


All times are GMT -5. The time now is 11:06 PM.