select() woes

This is a discussion on select() woes within the Linux Networking forums, part of the Linux Forums category; I created a very UDP simple server (Linux kernel 2.4.20) that listens on two ports --- 6000 & 7000. ...


Go Back   Usenet Forums > Linux Forums > Linux Networking

FAQ Members List Calendar Search Today's Posts Mark Forums Read
  #1 (permalink)  
Old 10-17-2006
Generic Usenet Account
 
Posts: n/a
Default select() woes

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
  #2 (permalink)  
Old 10-17-2006
Bob Hauck
 
Posts: n/a
Default Re: select() woes

["Followup-To:" header set to comp.os.linux.misc.]

On 17 Oct 2006 12:47:32 -0700, Generic Usenet Account
<usenet@sta.samsung.com> 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 Search this Thread
Search this Thread:

Advanced Search
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 Off
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



All times are GMT +1. The time now is 02:06 AM.


Powered by vBulletin® Version 3.7.3
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO 3.0.0