Jump to content
  • Advertisement
Sign in to follow this  
Solance

a strange select() problem

This topic is 4910 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

it seems to work fine for the first user but when another connection is made(any connection after) seems like in order for it to read anything form them one of the perviously opened connections has to send something and if all connections are closed the server recieves the connection but no data is handled

Share this post


Link to post
Share on other sites
Advertisement
The first parameter to select() must be the value of the largest file descriptor, plus 1. If you misspecify it, some fds may not be checked.

Share this post


Link to post
Share on other sites
yes i am adding one to my maximum file discriptor in my select call

if (select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1) {
cout<<"select\n";
exit(1);
}

for(i = fdmin-1; i <= fdmax+1; i++)
{

if(i!=1976)
{
if (FD_ISSET(i, &read_fds))
{

it just dosent make sense

Share this post


Link to post
Share on other sites
Windows ignores the first parameter, so if you're using Windows, changing it won't make any difference.
From my code:

// See if we should recv() //
nResult = select(0,&theSet,NULL,NULL,&theTimeout);
if(nResult == SOCKET_ERROR)
{
// Error handling
}

// Read //
for(DWORD i=0; i<theSet.fd_count; ++i)
{
// Read from the socket //
nResult = recv(theSet.fd_array,(char*)byBuff,nBufferSize,0);

// Append to internal buffer
}


theSet.fd_count gets the number of sockets in the set, I don't know if there's a non-Windows way to do this.

Your for(i = fdmin-1; i <= fdmax+1; i++) loop looks very wrong, were do you get the values for fdmin and fdmax? The OS doesn't have to return consecutive numbers for consecutive socket() calls (In fact Windows returns a number that's divisible by 4).

Share this post


Link to post
Share on other sites
some time it appears the server to be hanging even though a connection is established it just hangs maybe somthing is saying ok recieve data from this discriptor and it just hangs on recv()


i get my fdmin and fdmax when a connection is accepted if there port file discriptor is greater than current fdmax(listening socket by default) then that discriptor becomes the fdmax same goes for fdmin

Share this post


Link to post
Share on other sites
would having where it accepts connections and where it handles data in 2 seperate threads affect this?

Share this post


Link to post
Share on other sites
Quote:
Original post by Solance
would having where it accepts connections and where it handles data in 2 seperate threads affect this?
Nope. My server does that just fine.

You still shouldn't be looping like that, since you'll be checking sockets that don't exist, or you don't own. You should instead keep an array of sockets, and loop through that array to see if FD_ISSET returns true.

What OS is this running on?

Share this post


Link to post
Share on other sites
this is currently running on windows but with slight tweaking it should run cross platform


could i get a example of what you posted above?

Share this post


Link to post
Share on other sites
Sure, something like this:

// Globals
std::vector<SOCKET> g_vSockets; // Your array of sockets. a std::vector for simplicity
SOCKET g_maxFD = 0; // Highest numbered socket


// When you accept a connection
SOCKET sock = accept();
if(sock != SOCKET_ERROR)
{
g_vSockets.push_back(sock); // Add to the list of it's valid
if(sock > g_maxFD) g_maxFD = sock; // Update max FD
}


// When you come to recieve:
// Fill the set
FD_SET theSet;
FD_ZERO(&theSet);
for(size_t i=0; i<g_vSockets.size(); ++i)
FD_SET(g_vSockets,&theSet);
// See what ones have data pending
int nRet = select(g_maxFD,&theSet,NULL,NULL,NULL);
if(nRet == SOCKET_ERROR)
{
// Error
}

// Read the data
for(size_t i=0; i<g_vSockets.size(); ++i)
{
if(FD_ISSET(g_vSockets,&theSet))
{
// Read into a buffer of buffersize bytes
int nRead = recv(g_vSockets,buffer,buffersize,0);
}
}

Share this post


Link to post
Share on other sites
thanks alot ill try that kind of implimentation when i get home tommarow dont have time tonight :(

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!