My socket is broken :(

Started by
5 comments, last by Evil Steve 19 years, 7 months ago
Well, this is more than a little strange. I've never had this problem before, and I'm using the same socket class that I've been using for a year or so. I'm making an SMPT server, and I'm having a bit of difficulty with the accept()ed socket. I can call m_sockListen.Accept(sockClient); fine, and it gets the correct IP address for the client - so I know the socket is valid at this point. I then try calling select() on the returned socket, to check for data to read. This always returns 0, saying theres no data to read. I then close the client (Its just a telnet window at the moment), and select() for errors - But there aren't any. So it seems that windows doesn't know anything is going on. I thought that somehow the socket was being made invalid - But then select() would return -1. And also, I can closesocket() on the sockClient, and the client gets disconnected properly - so the socket has to be valid at this point. I've tried using telnet, my MUD client, and PuTTy as clients, and they all exhibit the same behaviour. Heres the code I use for checking for errors (almost identical to that for checking for data to read):

fd_set theSet;
timeval theTimeout;

	// Setup select() Structures //
	FD_ZERO(&theSet);
	FD_SET(sock,&theSet);
	theTimeout.tv_sec = 0;
	theTimeout.tv_usec = 0;

	// See if theres any errors //
	if(select(sock+1,NULL,NULL,&theSet,&theTimeout) != 0)
	{
		m_strError = WSAErrorAsString(Error);
		closesocket(sock);
		sock = INVALID_SOCKET;
		return false;
	}
	return true;
}


I check every single Winsock function for errors, and none return any sort of error code. Does anyone know what the hell is going wrong? Cheers, Steve
Advertisement
The only thing that looks out of place there to me is that you're calling select on sock + 1, an integer value. Why not just set that value to zero? In Richard Hallett's non-blocking tutorial on this site, he uses a variable nfds which he sets to zero where you use sock + 1.

Also, even though it shouldn't matter, as you're only checking for errors while I'm checking for both input and errors, my code looks like this:

	sl = select(nfds,&input_set,NULL,&exc_set,&to);	if (sl > 0) // Is there data coming in?	{		if (FD_ISSET(s,&exc_set)) // Error	    {	    		}		if ((FD_ISSET(s, &input_set))) // Data	    {			ReceiveMessage();		}	}


where s is your socket. See if that changes anything. This is a pretty strange problem though if it's never happened before.

EDIT: Fixed Source Tags
It's not clear what it is that you expect to happen. From your description it sounds like it's working just fine - the connection is established but there's no data available to read yet. When the connection is closed, the socket should become readable and recv() should return 0.

The exceptfds argument to select() is very rarely needed and using it does not seem relevant in this context. It does not detect a socket close, if that's what you were expecting.

GodlyGamr: Ignoring the nfds parameter is a Winsockism. It is required to be the highest-numbered descriptor + 1 for other socket implementations, and always using it that way will make porting easier.

[Edited by - spock on September 3, 2004 10:26:25 AM]
I have to functions: CheckReceive() and IsValid(). IsValid() checks the exceptfds parameter in select(), and CheckReceive() checks the readfds parameter.
When the socket is closed, theres still no events for exceptfds or readfds.
And I do send data from the client to the server, but the server doesn't seem to ever receive it (theres never a read notification).

And the reason for the first parameter to select() is that my socket code is portable, and works in Unix too (and Unix requires the first parameter to be valid, unlike Windows).

Thanks for the replies.
Out of curiosity, does it get better if you set a timeout of like, 5us instead of 0? The man page says select() will return 0 if it times out before anything interesting happens. It might also help to check for errors and reads at the same time (just have a readset and an exceptset) instead of running two seperate passes.

EDIT - When I say check for both at the same time, it's exactly what GodlyGamr suggested.
I see. You should be getting an event on readfds for received data as well as socket close. The only other thing I can think of right now is that if you are using port 25 the traffic might be intercepted by a firewall or antivirus software, causing the packets to be dropped. SMTP is often filtered nowadays.
I've tried setting different timeouts, from 5us to 5 seconds. Still no luck.

I'll try another port, but I don't think that should affect it - The client and server are on the same machine.

Uhm... Well thats strange...
I.. OH! I know what it is now >_<

spock - you're a life saver [wink]

For anyone interested:
Its because Norton Antivirus scans e-mail for you - So its intercepting the read calls so it can scan the mail before passing it to my SMTP server. Disabling Norton Antivirus gets it working perfectly

Thanks again [grin]

This topic is closed to new replies.

Advertisement