Title: WinSock connect() problem. Client thinks it is connected even when Server is down

As of right now, my program incorrectly displays the status of the connecting socket. Because of the if statements seen below, even when the server is down, my friends can access a part of the program which should only be available when successfully connected to the server.

On the client, they are accessing an input (which lets them send a message to the server) even when they are not connected to the server, where the program should have normally told them they failed to connect and would have closed the program.

Here is the code, can you help me fix up this if-statement so that it works properly?

//create the socket
        client = socket(AF_INET, SOCK_STREAM, 0);
	
	//set the socket I/O mode
	//if iMode = 0, blocking is enabled
	//if iMode != 0, non-blocking mode is enabled
	u_long iMode = 1;
	ioctlsocket(client, FIONBIO, &iMode); 

	//connect to the server
	if( connect( client, (sockaddr*)&server, sizeof(server) ) == SOCKET_ERROR)
	{
		if( WSAGetLastError() == WSAEWOULDBLOCK)
		{
			cout << "Attempting to connect.\n";
		}
		else
		{
			cout << "Failed to connect to server.\n";
			cout << "Error: " << WSAGetLastError() << endl;
			WSACleanup();
			system("pause");
			return 1;
		}
	}

To offer some help, the connect() SHOULD return WSAEWOULDBLOCK first, as it ATTEMPTS to connect. Eventually it will return 0 for success, or SOCKET_ERROR if it has failed. The error can be determined by the WSAGetLastError() function shown in the else block.
I can't seem to wrap my head around the logic required in order to setup the if-statements correctly after the first WSAEWOULDBLOCK check. Am I supposed to use select()? How do I do that? Thanks for the help!

Recommended Answers

All 4 Replies

Show your server socket code. If I'm right - you just forget to close server socket before shutting down the server.
And there are some errors in your client code. You forget to close socket after getting an error

//create the socket
        client = socket(AF_INET, SOCK_STREAM, 0);
	
	//set the socket I/O mode
	//if iMode = 0, blocking is enabled
	//if iMode != 0, non-blocking mode is enabled
	u_long iMode = 1;
	ioctlsocket(client, FIONBIO, &iMode); 

	//connect to the server
	if( connect( client, (sockaddr*)&server, sizeof(server) ) == SOCKET_ERROR)
	{
		if( WSAGetLastError() == WSAEWOULDBLOCK)
		{
			cout << "Attempting to connect.\n";
                                    closesocket(client);  //this 
		}
		else
		{
			cout << "Failed to connect to server.\n";
			cout << "Error: " << WSAGetLastError() << endl;
                                    closesocket(client); //and this
			WSACleanup();
			system("pause");
			return 1;
		}
	}

I hope it will help you.

Thanks for the help, but I know that is not the solution.

The client never connects to the server. The issue is that the client application will continue to the section that would be visible IF he was properly connected to the server.

I can't figure out how to setup the if statement so that it first passes the WSAEWOULDBLOCK check, and then properly checks to see if the connection has finished. Here is what MSDN says:

With a nonblocking socket, the connection attempt cannot be completed immediately. In this case, connect will return SOCKET_ERROR, and WSAGetLastError will return WSAEWOULDBLOCK. In this case, there are three possible scenarios:

* Use the select function to determine the completion of the connection request by checking to see if the socket is writeable.

//connect to the server
	iResult = connect(client, (sockaddr*)&server, sizeof(server));
	
	if(iResult == SOCKET_ERROR)
	{
		iError = WSAGetLastError();
		//check if error was WSAEWOULDBLOCK, where we'll wait
		if(iError == WSAEWOULDBLOCK)
		{
			cout << "Attempting to connect.\n";
			fd_set Write, Err;
			TIMEVAL Timeout;
			int TimeoutSec = 10; // timeout after 10 seconds

			FD_ZERO(&Write);
			FD_ZERO(&Err);
			FD_SET(client, &Write);
			FD_SET(client, &Err);

			Timeout.tv_sec = TimeoutSec;
			Timeout.tv_usec = 0;

			iResult = select(0,			//ignored
							 NULL,		//read
							 &Write,	//Write Check
							 &Err,		//Error Check
							 &Timeout);
			if(iResult == 0)
			{
				cout << "Connect Timeout (" << TimeoutSec << " Sec).\n";
				system("pause");
				return 1;
				
			}
			else
			{
				if(FD_ISSET(client, &Write))
				{
					cout << "Connected!\n";
				}
				if(FD_ISSET(client, &Err))
				{
					cout << "Select error.\n";
					system("pause");
					return 1;
				}
			}
		}
		else 
		{
			cout << "Failed to connect to server.\n";
			cout << "Error: " << WSAGetLastError() << endl;
			WSACleanup();
			system("pause");
			return 1;
		}
	}
	else
	{
		//connected without waiting (will never execute)
		cout << "Connected!\n";
	}

listen all I can connect and send messages at local but I can't connect in global. why? what should I do?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.