Link to home
Start Free TrialLog in
Avatar of basil365
basil365Flag for Ireland

asked on

c++ socket server - WSAEISCONN 10056 error

Hi,

I have created an app that communicates via tcp sockets. The socket isn't asynchronous (This suits my needs) and I'm receiving the error when trying to invoke listen() on the server after one successful call.

can anybody see why this is occurring?

socket.h:
#pragma once //Only process header files once
#pragma comment(lib, "WS2_32.lib") //Add "WS2_32.lib" as a linker input
#include <iostream> //Input/output stream
#include "WinSock2.h" //Include WinSock
 
using namespace std; //Standard namespace
 
const int STRLEN = 1024; //Max length of our messages
 
class Socket //Socket base class
{
    protected:
        WSADATA wsaData; //wsaData
        SOCKET mySocket; //Socket
        SOCKET myBackup; //Socket
        SOCKET acceptSocket; //Socket
        sockaddr_in myAddress; //Socket Address
    public:
        Socket(); //"Prototype" constructor<
        ~Socket(); //"Prototype" destructor
        bool SendData( char* ); //"Prototype" SendData
        bool RecvData( char*, int ); //"Prototype" RecvData
        void CloseConnection(); //"Prototype" CloseConnection
        void GetAndSendMessage(); //"Prototype" GetAndSendMessage
}; //End base class
 
class ServerSocket : public Socket //Create our server socket class (derived)
{
    public:
        void Listen(); //"Prototype" Listen
        void Bind( int port ); //"Prototype" Bind
        void StartHosting( int port ); //"Prototype" StartHosting
}; //End ServerSocket class
 
class ClientSocket : public Socket //Create our client socket class (derived)
{
    public:
        void ConnectToServer( const char *ipAddress, int port ); //"Prototype" ConnectToServer
};

Open in new window


Socket impl:
#include "stdafx.h"
#include "Socket.h"
 
Socket::Socket() //Constructor
{
    if( WSAStartup( MAKEWORD(2, 2), &wsaData ) != NO_ERROR ) //WsaStartup
    {
        cerr<<"Socket Initialization: Error with WSAStartup\n"+WSAGetLastError(); //Error
        system("pause"); //Pause the program
        WSACleanup(); //Clean up
        exit(10); //Exit
    }
 
    //Create a socket
    mySocket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP ); //Set our socket variable
 
    if ( mySocket == INVALID_SOCKET ) //If the socket didn't set correctly
    {
        cerr<<"Socket Initialization: Error creating socket"+WSAGetLastError()<<endl; //Error
        system("pause"); //Pause the program
        WSACleanup(); //Clean up
        exit(11); //Exit
    }
 
    myBackup = mySocket; //Set the backup socket to the socket
}
 
Socket::~Socket() //Destructor
{
    WSACleanup(); //Clean up
}
 
bool Socket::SendData( char *buffer ) //SendData
{
    send( mySocket, buffer, strlen( buffer ), 0 ); //Send the data
    return true; //Return true
}
 
bool Socket::RecvData( char *buffer, int size ) //RecvData
{
    int i = recv( mySocket, buffer, size, 0 );
    buffer[i] = '\0';
    return true;
}
 
void Socket::CloseConnection()
{
    //cout<<"==CLOSE CONNECTION=="<<endl;
    closesocket( mySocket ); //Close the socket
    mySocket = myBackup; //Set the socket to the backup
}
 
void Socket::GetAndSendMessage() //GetAndSendMessage
{
    char message[STRLEN];//Char array
    cin.ignore();//Without this it uses the return char from last cin and passes this one!
    cout<<"> ";
    cin.get( message, STRLEN ); //Get the message
    SendData( message ); //Send the data
}
 
void ServerSocket::StartHosting( int port ) //StartHosting (for our ServerSocket class)
{
     Bind( port ); //Bind to the port
     Listen(); //Listen for connection attempts
}
 
void ServerSocket::Listen() //Listen (for our ServerSocket class)
{
    //cout<<"LISTEN FOR CLIENT..."<<endl;
 
    if ( listen ( mySocket, 1 ) == SOCKET_ERROR ) //If there is a problem
    {
		 int i = WSAGetLastError();
        cerr<<"ServerSocket: Error listening on socket\n"+WSAGetLastError(); //Error
        system("pause"); //Pause the program
        WSACleanup(); //Clean up
        exit(15); //Exit
    }
 
    //cout<<"==ACCEPT CONNECTION=="<<endl;
 
    acceptSocket = accept( myBackup, NULL, NULL ); //Attempt to accept connection
    while ( acceptSocket == SOCKET_ERROR ) //While there is a problem
    {
        acceptSocket = accept( myBackup, NULL, NULL ); //Try to accept
    }
    mySocket = acceptSocket; //Set mySocket to acceptSocket
}
 
void ServerSocket::Bind( int port ) //Bind (for our ServerSocket class)
{
    myAddress.sin_family = AF_INET; //sin_family is always supposed to be AF_INET
    myAddress.sin_addr.s_addr = inet_addr( "0.0.0.0" ); //IP it connects to (dont need for server)
    myAddress.sin_port = htons( port ); //The port
 
    //cout<<"==BIND TO PORT=="<<port<<endl;
 
    if ( bind ( mySocket, (SOCKADDR*) &myAddress, sizeof( myAddress) ) == SOCKET_ERROR ) //If there is a problem
    {
        cerr<<"ServerSocket: Failed to connect\n"+WSAGetLastError(); //Error
        system("pause"); //Pause the program
        WSACleanup(); //Clean up
        exit(14); //Exit
    }
}
 
void ClientSocket::ConnectToServer( const char *ipAddress, int port ) //ConnectToServer (for our ClientSocket class)
{
    myAddress.sin_family = AF_INET; //sin_family is always supposed to be AF_INET
    myAddress.sin_addr.s_addr = inet_addr( ipAddress ); //IP it connects to
    myAddress.sin_port = htons( port ); //The port
 
    //cout<<"==CONNECTED=="<<endl;
 
    if ( connect( mySocket, (SOCKADDR*) &myAddress, sizeof( myAddress ) ) == SOCKET_ERROR ) //If there is a problem
    {
        cerr<<"ClientSocket: Failed to connect\n"+WSAGetLastError(); //Error
        system("pause"); //Pause the program
        WSACleanup(); //Clean up
        exit(13); //Exit
    }
}

Open in new window


SocketServer class
#include "stdafx.h"
#include "SocketServer.h"
#include <vector>
#include <iterator>

bool NFLSocketServer::run()
{
	cout<<"==HOSTING=="<<endl; //Tell the user we are hosting
    //sockServer.StartHosting( port ); //StartHosting

	sockServer.Bind(this->port);

	this->done = false;
	//Connected
	bool connected = false;


	while ( !done )
	{
		cout << "Listening for connections..." << endl;

		sockServer.Listen();

		connected = true;

		while(connected)
		{
			//initialise buffer
			//vector<string> buffer;
			string accum;
			bool filling = true;
			//fill the buffer
			while(filling)
			{
				cout << "-------- READ ---------" << endl;
				//read off socket
				sockServer.RecvData( recMessage, STRLEN ); //Receive data
       
				string msg(recMessage);
				cout << msg << endl;
				Message::trim(msg);
				accum += msg + " ";


				if(accum.size() > 0 && accum.find(" end ")!= string::npos )
				{
					filling = false;
				}
			}


			vector<string> buffer = Message::split(accum);
			
			
			if(buffer.size() > 0 )
			{
				//buffer.back().compare("end")==0
				int backIndex = buffer.size()-1;
				while(buffer[backIndex].compare("")==0 && backIndex >=0)
				{
					backIndex--;
				}

				if(buffer[backIndex].compare("end")==0)
				{
					cout << "Buffer filled" << endl;
					this->process(buffer);
				}
				else 
				{
					cout << "invalid buffer. " << endl;
				}
			}
			else 
			{
				cout << "invalid buffer. " << endl;
			}
		
			connected = false;
		}
	}
	return done;
}

bool NFLSocketServer::process(vector<string> data)
{
	//internal logic, i dont think this affects server execution

	return success;
}

void NFLSocketServer::setIPAddress(string ip)
{
	this->ipAddress = ip;
}

void NFLSocketServer::setPort(int portNum)
{
	this->port = portNum;
}


}

Open in new window



An exception is thrown on this line: sockServer.Listen(); after one call has been processed.

Any help appreciated
ASKER CERTIFIED SOLUTION
Avatar of mccarl
mccarl
Flag of Australia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of basil365

ASKER

Thanks for your help guys - i'll follow your points and clean it up a bit.