Networking Forums

Networking Forums > Computer Networking > Linux Networking > select() woes

Reply
Thread Tools Display Modes

select() woes

 
 
Generic Usenet Account
Guest
Posts: n/a

 
      10-17-2006, 07:47 PM
I created a very UDP simple server (Linux kernel 2.4.20) that listens
on two ports --- 6000 & 7000. I am using select(), but I am seeing
some unexpected behavior. The server seems to get "locked" on to the
port number on which it receives its first message. For example, if
the first message to the server is sent on port 6000, it will receive
all subsequent messages on port 6000, but it will simply ignore all
messages on port 7000. Similarly, if the first message to the server
is sent on port 7000, it will receive all subsequent messages on port
7000, but it will turn deaf to port 6000.

I am sure that there is some careless mistake on my part. Any help
will be appreciated.

Regards,
Song

///// Sample Source Code /////
#include <unistd.h>
#include <ctype.h>
#include <iostream>
#include <time.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <arpa/inet.h>

using namespace std;

#define MAXMESG 2048

#define PORT_1 6000
#define PORT_2 7000


int maxDescriptor_g = 0;

//////////////////////////////////////////////////////////
//
// Simply dumps the message contents in hex
//
//////////////////////////////////////////////////////////
void
printMessage(void *msg, size_t msgLen)
{
ios_base::fmtflags oldFmtSettings = cout.setf(ios::showbase);
char *msgPtr = (char *)msg;
for(size_t i = 0; i < msgLen; i++)
{
if(!(i%10))
cout << endl;
unsigned char ch = *(msgPtr+i);
cout << hex << int(ch) << " ";
}
cout << endl;
cout.setf(oldFmtSettings);

cout <<"\n\n\n";
}


//////////////////////////////////////////////////////////
//
// Processes incoming message
//
//////////////////////////////////////////////////////////
void
processMsg(int sockd)
{
int bytesRead, clilen;

char mesg[MAXMESG];
sockaddr_in from;

size_t addrLen = sizeof(sockaddr_in);
size_t msgLen;


for(;
{
bytesRead = recvfrom(sockd, mesg, MAXMESG, 0,(sockaddr*) &from,
(socklen_t *)&addrLen);
if(bytesRead < 0)
{
cerr << "recvfrom: error" << endl;
continue;
}

cout << "Received following message from " <<
inet_ntoa(from.sin_addr)
<< ":\n";
printMessage(mesg, bytesRead);
break;
}
}


//////////////////////////////////////////////////////////
//
// Makes calls to socket(), bind() etc.
//
//////////////////////////////////////////////////////////
int
registerNewListener(int& sd, unsigned short portNum, fd_set& readSet)
{
sockaddr_in serverDetails;
serverDetails.sin_family = AF_INET;
serverDetails.sin_addr.s_addr = htonl(INADDR_ANY);
serverDetails.sin_port = htons(portNum);

socklen_t serverAddrLen = sizeof(sockaddr_in);

if((sd=socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
cerr << "server: can't open datagram socket" << endl;
return -1;
}

if(bind(sd, (const sockaddr*)&serverDetails, serverAddrLen) < 0)
{
cerr << "server: can't bind local address" << endl;
close(sd);
return -2;
}

int on = 1;
if(ioctl(sd, FIONBIO, &on) < 0)
{
cerr << "server: can't set the socket to non-blocking" << endl;
return -3;
}

FD_SET(sd, &readSet);

if(sd > maxDescriptor_g)
maxDescriptor_g = sd;

return 0;
}


//////////////////////////////////////////////////////////
//
// main
//
//////////////////////////////////////////////////////////
main(int argc, char *argv[])
{
int sockd1, sockd2;

fd_set readFDSet;
FD_ZERO (&readFDSet);

if(registerNewListener(sockd1, PORT_1, readFDSet) < 0)
{
return -1;
}


if(registerNewListener(sockd2, PORT_2, readFDSet) < 0)
{
return -1;
}

for(;
{
int rc;
if((rc = select(maxDescriptor_g+1, &readFDSet, NULL, NULL, NULL)) <
1)
{
cerr << "server: Bad return value from select (" << rc << ")\n";
return -3;
}

if(FD_ISSET(sockd1, &readFDSet))
processMsg(sockd1);

if(FD_ISSET(sockd2, &readFDSet))
processMsg(sockd2);
}
}

 
Reply With Quote
 
 
 
 
Bob Hauck
Guest
Posts: n/a

 
      10-17-2006, 10:50 PM
["Followup-To:" header set to comp.os.linux.misc.]

On 17 Oct 2006 12:47:32 -0700, Generic Usenet Account
<(E-Mail Removed)> wrote:

> I created a very UDP simple server (Linux kernel 2.4.20) that listens
> on two ports --- 6000 & 7000. I am using select(), but I am seeing
> some unexpected behavior. The server seems to get "locked" on to the
> port number on which it receives its first message.


[snip code]

> main(int argc, char *argv[])
> {
> int sockd1, sockd2;
>
> fd_set readFDSet;
> FD_ZERO (&readFDSet);
>
> if(registerNewListener(sockd1, PORT_1, readFDSet) < 0)
> {
> return -1;
> }
>
>
> if(registerNewListener(sockd2, PORT_2, readFDSet) < 0)
> {
> return -1;
> }
>
> for(;
> {
> int rc;
> if((rc = select(maxDescriptor_g+1, &readFDSet, NULL, NULL, NULL)) <
> 1)
> {
> cerr << "server: Bad return value from select (" << rc << ")\n";
> return -3;
> }
>
> if(FD_ISSET(sockd1, &readFDSet))
> processMsg(sockd1);
>
> if(FD_ISSET(sockd2, &readFDSet))
> processMsg(sockd2);
> }
> }


You only ever configure readFDSet in registerNewListener(). If you were
to read the man page for select() you would see this:

On exit, the sets are modified in place to indicate which file
descriptors actually changed status.

This means that you need to call FD_SET() again before each call to
select(). If you don't do that, then the set will only contain the
descriptors that changed, thus explaining the behavior you are seeing.


--
-| Bob Hauck
-| Have you had enough of George Bush yet?
-| http://www.haucks.org/
 
Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Strange problem with select (or maybe me :-)) pistmaster@googlemail.com Linux Networking 1 09-17-2008 08:59 PM
AF_PACKET and select Gisle Vanem Linux Networking 0 12-15-2004 01:08 PM
select() waiting for timeout before doing anything Frank de Bot Linux Networking 3 12-07-2004 08:05 PM
Regarding behaviour of select() all Rajat Linux Networking 1 10-09-2004 08:54 PM
Help with Select Marcia Hon Linux Networking 3 02-20-2004 05:50 PM



1 2 3 4 5 6 7 8 9 10 11