Jump to content
  • Advertisement
Sign in to follow this  
roby65

"Emulating" polls with fd_set

This topic is 3047 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

Hi guys, i have a netcode that uses polls for polling sockets. But i have to compile it on a system that doesn't support polls, so i made this: #define POLLIN 1 #define POLLOUT 2 #define POLLERR 4 #define POLLHUP POLLERR #define POLLPRI 8 #define POLLNVAL POLLERR struct pollfd { int fd; unsigned char events; //What events to capture unsigned char revents; //Events captured }; int poll(struct pollfd* socklist,int count, int unk) { fd_set read_flags,write_flags; int i=0,ret; struct timeval waitd; int maxfd=0; waitd.tv_sec = 0; waitd.tv_usec = 5; FD_ZERO(&read_flags); FD_ZERO(&write_flags); for (i=0;i<count;i++) { if((socklist->fd)<0) continue; if(socklist->events & POLLIN) FD_SET(socklist->fd, &read_flags); if(socklist->events & POLLOUT) FD_SET(socklist->fd, &write_flags); if ((socklist->fd)>maxfd) { maxfd=socklist->fd; } } ret=select((maxfd)+1, &read_flags,&write_flags,(fd_set*)0,&waitv); if(ret<0) { //Error handling } for (i=0;i<count;i++) { if((socklist->fd)<0) continue; if(socklist->events & POLLIN) if(FD_ISSET(socklist->fd,&read_flags)) { socklist->revents |=POLLIN; } if(socklist->events & POLLOUT) if(FD_ISSET(socklist->fd,&write_flags)) { socklist->revents |=POLLOUT; } } return 1; } Is it right? Cause FD_ISSET always return 1, so the program thinks that the socket is ready for send and recv when it's not.... Why?

Share this post


Link to post
Share on other sites
Advertisement
I think there is an error condition whereby a socket can be flagged as ready to receive, you then need to check to see how much data is waiting, if data == 0, then the socket was closed.

Here is some of my socket code:

if (m_clientSocket->Select(
(int)(socketFD)+1,
&readSet,
&writeSet,
NULL,
0) != -1)
{
if (FD_ISSET(socketFD, &readSet))
{
res |= PRES_CAN_RECIEVE;
}
if (FD_ISSET(socketFD, &writeSet))
{
res |= PRES_CAN_SEND;
}

//-----------------------------
// Check to see if the socket has been closed
//-----------------------------
if (res & PRES_CAN_RECIEVE)
{
char buffer[1];
if (recv(m_clientSocket->GetSocketDescriptor(),
buffer,
1,
MSG_PEEK) == 0)
{
res = PRES_CONNECTION_CLOSED;
}
}
}
else
{
HandleSocketError();
return PRES_ERROR_OCCURED;
}



Regards,

Alex

Share this post


Link to post
Share on other sites
I don't think that the recv is the problem.
The problem (i think) is that connect is non-blocking, so after the connect it's flagged as writable also if it's not still connected

Share this post


Link to post
Share on other sites
Does ISSET_FD return true for both read and write, or just one of them?

If you are testing a socket, it will most likely come back as ready to send (unless the output buffer is full), but not receive unless data is actually waiting (or if socket was closed as in my last post).

Alex

Share this post


Link to post
Share on other sites
it always tell me that i can both read and write, and the socket is connecting/connected, so it is not closed

Share this post


Link to post
Share on other sites
I don't see you clearing revents in your emulation code.
In your first "count" loop, you should probably clear that to 0.

Share this post


Link to post
Share on other sites
I found the problem:
the connect is async so it returns immediately, and it takes some time to connect.
But select returns that the socket is ready to send.
And when i send, errno is 128 (ENOTCONN 128 /* Socket is not connected */)
Probably because it's still connecting.
So, why does select tells me that the socket is ready to send?

Share this post


Link to post
Share on other sites
As I understand it, select doesn't attempt to guess at the state of your connection. It simply tells you whether that socket is physically ready for reading or writing (usually based on buffer contents or free space). How much data you get or where it goes when you send it is another matter.

Share this post


Link to post
Share on other sites
Quote:
Original post by Kylotan
As I understand it, select doesn't attempt to guess at the state of your connection. It simply tells you whether that socket is physically ready for reading or writing (usually based on buffer contents or free space). How much data you get or where it goes when you send it is another matter.


The socket is NOT physically ready for writing because it's not still connected, but select tells me that the socket is ready for sending and receiving

Share this post


Link to post
Share on other sites
The socket IS physically ready because it's got free buffer space for you to fill up. Select's readiness does not tell you "whatever you send will arrive at the intended destination". Select tells you "if you write something now, I won't have to tell you to wait while I make room to buffer the data".

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.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!