Sign in to follow this  

select() issue

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

I've been doing network code for a long time, and select has always given me problems. My last project I finished was always a little buggy from the start and I think it was because of select. I have the same code (except modified so it fits a new program) and now it isn't working period. Can anyone tell me where I've gone wrong? I learned how to do network programming from beej's socket guide and this is basically how beej's guide explains how to use select. The problem is it returns -1 right away, it doesn't wait 3 seconds and return 0 or an integer like I would expect. I think the problem might have to do with the FD_SET, but thats just a guess. Can anyone help me out? I would really appreciate it.
	SOCKET sockfd, new_fd;
	struct sockaddr_in my_addr;
	struct sockaddr_in their_addr;
	int sin_size, socks, rv;
	
	sockfd = socket(PF_INET, SOCK_STREAM, 0);

	my_addr.sin_family = AF_INET;
	my_addr.sin_port = htons(7869);
	my_addr.sin_addr.s_addr = INADDR_ANY;

	memset(&(my_addr.sin_zero), '\0', 8);

	bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr));

	listen(sockfd, 1);

	sin_size = sizeof(struct sockaddr_in);
	
	fd_set selectfds;
	timeval tv;
	
	FD_ZERO(&selectfds);
	
	FD_SET(new_fd, &selectfds);
	
	socks = new_fd + 1;
	
	tv.tv_sec = 3;
	tv.tv_usec = 0;
	
	rv = select(1, &selectfds, NULL, NULL, &tv);
	
	if (rv == -1)
	{
		cout << "select error.";
	}
	else if (rv == 0)
	{
		cout << "nothing to select.";
	}
	else
	{
		if (FD_ISSET(new_fd, &selectfds))
		{
			cout << "accepting.";
		}
	}

Share this post


Link to post
Share on other sites
1. What is "new_fd"? Seems like it's not a valid socket.
2. bind, listen - they return error codes, nice to check for those.
3. strerror is your friend.
4. IIRC, you're supposed to use htonl(INADDR_ANY).
5. memset(&(my_addr.sin_zero), '\0', 8); - never heard of this, nor seen in any sample (but I might be misinformed).

EDIT:
6. rv = select(1, &selectfds, NULL, NULL, &tv); - first parameter should be "new_fd+1".

HTH.
~def

Share this post


Link to post
Share on other sites
Quote:
select(1, &selectfds, NULL, NULL, &tv);


That "1" should really be "socks" which you calculated above.

Also, you should check errors for calls to bind(), listen() etc. Bind(), for example, might fail when you re-start a program, unless you set the SO_REUSEADDR socket option.

Share this post


Link to post
Share on other sites
I know that the example is poorly coded and illogical, but thats only because it serves no purpose besides figuring out what I'm doing wrong. By the way deffer, htonl(INADDR_ANY) is the same thing as INADDR_ANY, just so you know. And yes before you repond with something along the lines of "its a bad habbit," I already know.

Anyways, bind and listen are not the problem. I didn't have it check for errors, because I was pretty confident that bind and listen wern't going to cause an error. I added error checking in just to make sure, and found that they wern't the problem. I chagned socks to one earlier to see if socks was the problem and forgot to change it back. I changed it back, and it still is giving the same error.

maybe I've been doing error checking wrong all along?


if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == SOCKET_ERROR)
{
WSACleanup();
cout << "bind";
cin >> c;
return 0;
}

if (listen(sockfd, 1) == SOCKET_ERROR)
{
WSACleanup();
cout << "listen";
cin >> c;
return 0;
}


If there anything else that can cause the problem? Select has always given me problems, so I'm really not entirely sure I'm doing everything right to check myself. So if you see anything please let me know. Thank you for your time.

Share this post


Link to post
Share on other sites
Let me reiterate:
1. What is "new_fd"? Seems like it's not a valid socket.
3. strerror is your friend
if (rv == -1)
{
cout << "select error.";
cout << strerror(errno) << std::endl;
}


-----
Uh, it's windows? Then first parameter to select() call is ignored anyway[grin]

Share this post


Link to post
Share on other sites
Quote:
Original post by yahn
Cout's no error.

I don't understand.
There's no error description given? select docs clearly state that errno should be set to appropriate error if select returns -1.

Quote:
Original post by yahn
new_fd doesn't really do anything. it's just a socket that when an connection is made it is set to.

There's no accepting in your code. Maybe I'm missing something? If so, post all the relevant code, please.

Share this post


Link to post
Share on other sites
No, you arn't missing anything. I'm just trying to see why select doesn't work. is that what could be causing the problem? new_fd is just a socket when its being selected it hasn't been connected yet.

Share this post


Link to post
Share on other sites
Quote:
Original post by yahn
is that what could be causing the problem? new_fd is just a socket when its being selected it hasn't been connected yet.


That was my main point from the start.
select @ msdn

You aren't expected to put an invalid socket to FD_SET. You are expected to put your "sockfd" instead. And call accept manually when select succesfully returns.

Share this post


Link to post
Share on other sites
No, it should be perfectly valid to select() on a listening socket. The select() will return whether you can call accept() on the socket in this case.

If you are on Windows:
1) make sure you call WSAStartup() and pass in 2,2 as the WinSock version.
2) you have to use the socket errno function; "errno" doesn't work with sockets.
3) You can also try WSAGetLastError().

Share this post


Link to post
Share on other sites
Quote:
Original post by hplus0603
No, it should be perfectly valid to select() on a listening socket.


Yeah, but he's calling FD_SET on an uninitialised socket variable. Surely he should be passing sockfd, not new_fd. new_fd would get assigned by the accept() call.

Share this post


Link to post
Share on other sites

This topic is 4109 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this