LinuxQuestions.org
Review your favorite Linux distribution.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 02-04-2011, 04:56 PM   #1
vbx_wx
Member
 
Registered: Feb 2010
Posts: 181

Rep: Reputation: 16
Connect() gives error in c++


Code:
class Socket {
protected:
    int desc;
public:
    Socket()
    {
        desc = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if(desc == SOCKET_ERROR)
        {
            cout << "Error in Socket()" << strerror(errno) << endl;
        }
    }
    Socket(int desc)
    {
        this->desc = desc;
    }
    ~Socket()
    {
#ifdef WIN32
        ::closesocket(desc);
#else
        ::close(desc);
#endif
    }

};

class TCPSocket: public Socket {
public:
    TCPSocket(): Socket() {}
    TCPSocket(int sockDesc): Socket(sockDesc) {}
    int Send(const char* buffer, int size)
    {
        return ::send(desc, buffer, size, 0);
    }
    int Recv(char* buffer, int size)
    {
        return ::recv(desc, buffer, size, 0);

    }
};

class ServerSocket: public Socket {
private:
    sockaddr_in server;
public:
    ServerSocket(): Socket()
    {
        memset(&server, 0, sizeof(server));
        server.sin_family = AF_INET;
        server.sin_addr.s_addr = INADDR_ANY;
        server.sin_port = htons(9898);
    }
    void Bind()
    {
        if((::bind(desc, (sockaddr*)&server, sizeof(server))) == SOCKET_ERROR)
        {
            cout << "Error in Bind()" << endl;
        }
    }
    void Listen()
    {
        if((::listen(desc, 5)) == SOCKET_ERROR)
        {
            cout << "Error in Listen()" << endl;
        }
    }
    TCPSocket* Accept()
                            {
        int remoteSocket = ::accept(desc, 0, 0);
        if(remoteSocket == SOCKET_ERROR)
        {
            cout << "Error in Accept()" << endl;
            exit(1);
        }
        return new TCPSocket(remoteSocket);
                            }
};

class ClientSocket: public TCPSocket {
private:
    sockaddr_in client;
public:
    ClientSocket(): TCPSocket()
    {

    }
    void Connect(string address, unsigned short port)
    {
        memset(&client, 0, sizeof(client));
        client.sin_family = AF_INET;
        client.sin_addr.s_addr = inet_addr(address.c_str());
        client.sin_port = htons(port);


        if((::connect(desc, (sockaddr*)&client, sizeof(client))) == -1)
        {
            cout << "Error in Connect()" << strerror(errno) << endl;
        }
    }
};

void Initialize()
{
    WSAData wsadata;
    if(WSAStartup( MAKEWORD( 1, 1 ), &wsadata ) != 0 )
    {
        cout << "Error creating socket" << endl;
        exit(1);
    }
    wsadata.wVersion = 5;
}

class Handle {
    TCPSocket* sock;
    char* destinationAddress;
    short port;
public:
    Handle(TCPSocket* s)
    {
        destinationAddress = new char[30];
        port = 0;
        sock = s;
    }
    ~Handle()
    {
        delete [] destinationAddress;
    }
    void HandleConnection()
    {
        //code here

        ClientSocket c;
        c.Connect(destinationAddress, port);
    }
};

void* threadMain(void* arg)
{
    static int count = 0;
    pthread_t thread_id = pthread_self();
    cout << "Thread " << count << " at work" << endl;
    Handle handle((TCPSocket*)arg);
    handle.HandleConnection();
    cout << "Thread " << count << " has finished" << endl;
    ++count;
    return 0;
}

int main()
{
#ifdef WIN32
    Initialize();
#endif
    pthread_t id;
    ServerSocket s;
    s.Bind();
    s.Listen();
    while(true)
    {
        TCPSocket* sock = s.Accept();
        if(pthread_create(&id, NULL, threadMain, (void*)sock) != 0)
        {
            cout << "Error creating thread" << endl;
        }
        pthread_join(id, NULL);
    }
    return 0;
}
When i call Connect() in side HandleConnection() it returns -1 and when i set strerror(errno) it returns "No Error" with value 0. Anyone has an idee what am i doing wrong ?
 
Old 02-04-2011, 06:38 PM   #2
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
Store errno in a temporary variable before printing it; std::cout << probably resets it to 0 before it's accessed.
Kevin Barry
 
Old 02-04-2011, 06:51 PM   #3
dwhitney67
Senior Member
 
Registered: Jun 2006
Location: Maryland
Distribution: Kubuntu, Fedora, RHEL
Posts: 1,541

Rep: Reputation: 335Reputation: 335Reputation: 335Reputation: 335
wbx_wx, what are you trying to accomplish?

When you kick off the thread, and then (almost) immediately perform the pthread_join(), you are blocking your main-thread from continuing until the child-thread completes. What is the point of that?

As for your thread, what is the purpose of HandleConnection(). You already have a socket that is "connected" to the external client. Think of it as a two-lane highway to the remote client. There's no need to setup yet another connection. The TCPSocket arg you have is quite capable of sending and receiving on it's own.


P.S. Forget for now programming for multiple platforms (i.e. Linux and Windows). Choose one, and stick with it. When you are completely done with everything, then focus on porting (to the other platform).
 
Old 02-05-2011, 06:12 AM   #4
vbx_wx
Member
 
Registered: Feb 2010
Posts: 181

Original Poster
Rep: Reputation: 16
Ok,i see that there was no point to use thread,after removing it my error in connect is "Result too large". HandleConnection() is just a function for performing some exghange of packets between client and this server,and when its all good i want to connect from this to another server,me acting like a proxy server.

edit: i found this thread http://www.developpez.net/forums/d91...ult-too-large/ . Someone its having the exact problem like me,but it is in french,if someone know french let me know.

edit2: changing it to work only for linux,the error is "Network is unreachable"

Last edited by vbx_wx; 02-05-2011 at 08:44 AM.
 
Old 02-05-2011, 09:37 AM   #5
vbx_wx
Member
 
Registered: Feb 2010
Posts: 181

Original Poster
Rep: Reputation: 16
I forgot about Google translate,after reading that thread,one sugestion was to replace inet_addr with inet_aton(). After doing this,it gives me "Connection refused".
 
Old 02-05-2011, 10:19 AM   #6
dwhitney67
Senior Member
 
Registered: Jun 2006
Location: Maryland
Distribution: Kubuntu, Fedora, RHEL
Posts: 1,541

Rep: Reputation: 335Reputation: 335Reputation: 335Reputation: 335
Are you attempting to put together a Server that serves as a data forwarder so that a Client can in essence send data to another Server? If you are, the first Server will need to be given (or it could be hard-coded) information on where to connect to the remote Server. And for now, I would push the multi-threading thoughts to the back-burner; worry about it later.

Consider something like:
Code:
int main(int argc, char** argv)
{
   try
   {
      TCPServerSocket listenSocket;

      listenSocket.bind(0, 12345);   // bind socket to INADDR_ANY and port 12345
      listenSocket.listen();

      while (true)
      {
         TCPSocket* client = listenSocket.accept();

         if (client)
         {
            handleClient(client);
         }
      }

      //...
   }
   catch (std::exception& e)
   {
      std::cerr << e.what() << std::endl;
   }
}


void handleClient(TCPSocket* client)
{
   try
   {
      TCPClientSocket forwarder;

      forwarder.connect("192.168.1.110", 54321);    // attempt to establish foreign connection

      bool connected = true;

      while (connected)
      {
         char buf[1024];

         int len = client->recv(buf, sizeof(buf));

         if (len > 0)
         {
            forwarder.send(buf, len);
         }
         else if (len == 0)
         {
            std::cout << "Client disconnected." << std::endl;
            connected = false;
         }
         else
         {
            // error attempting to receive data from the client
         }
      }

      // forwarder will also disconnect when it falls out of scope.
   }
   catch (std::exception& e)
   {
      std::cerr << e.what() << std::endl;
   }

   delete client;   // close client connection;
}
The code above assumes that your TCP Socket classes will augment their error handling to throw an exception should something fail. The alternative is to use C-style return codes (yuck!), and to check these after each call to bind(), listen(), accept(), connect(), etc.

It also assumes that the 'forwarder' will only send data; it will not receive. I would suggest that you study how to use select() so that you can handle both the client and the forwarder with regards to receiving data. Remember, recv() is a blocking call; you don't really want to call recv() on a socket unless you know for fact that their is data to be read. select() will assist you in determining whether there is data available.

Last edited by dwhitney67; 02-05-2011 at 10:26 AM.
 
Old 02-05-2011, 10:30 AM   #7
vbx_wx
Member
 
Registered: Feb 2010
Posts: 181

Original Poster
Rep: Reputation: 16
Yes thats is what i am trying to do,but to take your example the line:
Code:
forwarder.connect("192.168.1.110", 54321);
gives me error. That is my problem,i do not know what it wont connect.

For example:
Code:
CLient ---> My Server ---> Server
A client connects to me,after that it enters the HandleConnection function,where the authetication is made by sending and receiving packets.The last packet i rceived from the Client contains an address(ip,or domain) and a port,witch i extract from the packet and call Connect() to establish a connection between me(My Server) and Server. Here it gives me error.

The return value of client.sin_addr.s_addr = inet_addr(address.c_str()); is -1 and it gives "Result too large". So i am sure that,there is my problem. But when i try in a separate program to call Connect("www.google.com", 80) it works with the same code. I dont get it why here it doesnt work

Last edited by vbx_wx; 02-05-2011 at 10:44 AM.
 
Old 02-05-2011, 10:45 AM   #8
dwhitney67
Senior Member
 
Registered: Jun 2006
Location: Maryland
Distribution: Kubuntu, Fedora, RHEL
Posts: 1,541

Rep: Reputation: 335Reputation: 335Reputation: 335Reputation: 335
The only way that the connect() will work is if a Server is indeed listening at the foreign addr/port. Do you have that other server running? Can you confirm that it has called bind(), listen(), and accept()?
 
Old 02-05-2011, 11:14 AM   #9
vbx_wx
Member
 
Registered: Feb 2010
Posts: 181

Original Poster
Rep: Reputation: 16
Well i want to connect to this: www.google.com. So while there server is up and running i guess it should work no ? Again, making a simple client to connect to google works,the Connect() function doesnt give any error. In my program trying to connect to google gives error.

edit: i take that back,it doesnt work even with a simple client, i was not testing good the return value from connect.

Last edited by vbx_wx; 02-05-2011 at 11:33 AM.
 
Old 02-05-2011, 11:35 AM   #10
dwhitney67
Senior Member
 
Registered: Jun 2006
Location: Maryland
Distribution: Kubuntu, Fedora, RHEL
Posts: 1,541

Rep: Reputation: 335Reputation: 335Reputation: 335Reputation: 335
Google has port 80 open, thus there should be no reason why you should not be able to connect. Perhaps you need to revisit the code implemented in your Connect() function. Personally, I would have it call a function similar to the following to setup the sockaddr struct that is necessary for the ::connect() system library function.

Code:
int fillAddress(int domain, const char* address, unsigned short port, struct sockaddr_in* sin)
{
  if (address == 0 || strlen(address) == 0)
  {
    memset(sin, 0, sizeof(sockaddr_in));

    sin->sin_family      = domain;
    sin->sin_addr.s_addr = htonl(INADDR_ANY);
    sin->sin_port        = htons(port);
  }
  else
  {
    addrinfo hints;

    memset(&hints, 0, sizeof(hints));
    hints.ai_family = domain;

    addrinfo* host_info = 0;

    char portstr[6] = {0};
    snprintf(portstr, sizeof(portstr), "%d", port);

    if (getaddrinfo(address, portstr, &hints, &host_info) != 0  ||
        !host_info || !host_info->ai_addr || host_info->ai_family != domain)
    {
      if (host_info) freeaddrinfo(host_info);
      return -1;
    }

    memcpy(sin, host_info->ai_addr, sizeof(sockaddr_in));
    sin->sin_port = htons(port);

    freeaddrinfo(host_info);
  }
  return 0;
}
For your code:
Code:
void Connect(const string& address, const unsigned short port)
{
   sockaddr_in sin;

   if (fillAddress(AF_INET, address.c_str(), port, &sin) ||
       ::connect(desc, (sockaddr*)&sin, sizeof(sin)))
   {
      cout << "Error in Connect()" << strerror(errno) << endl;

      // You need better error handling here; a mere cout is not enough.
   }
}
Btw, once you connect to Google's port 80 (HTTP port), what do you plan to do then? Will you have a web-browser connect to your Server so that it's requests will be forwarded to Google?

Last edited by dwhitney67; 02-05-2011 at 11:38 AM.
 
Old 02-05-2011, 11:37 AM   #11
vbx_wx
Member
 
Registered: Feb 2010
Posts: 181

Original Poster
Rep: Reputation: 16
Maybe you have a point, if i set up another server,my proxys erver connects to it.
 
Old 02-05-2011, 11:59 AM   #12
vbx_wx
Member
 
Registered: Feb 2010
Posts: 181

Original Poster
Rep: Reputation: 16
Well i am using this client Proxifier,in his settings i can set where i want to connect.For example i put it on google,port 80,and there is an option Load a default web page from the host. I just wanna to this,so i can see it works.If i dont select that option with load a web page,the client programs says:
Code:
Connection to www.google.com:80 established through the proxy server
Kind if confusing,since i didnt even call Connect(). I' doing this for the first time,thats why i am a litlle confuse.

edit: btw your code doesnt give an error anymore,but its hard for me in linux since i dont have this program to test it,and in windows i dont have thoose functions you use.

Last edited by vbx_wx; 02-05-2011 at 12:01 PM.
 
Old 02-05-2011, 12:19 PM   #13
vbx_wx
Member
 
Registered: Feb 2010
Posts: 181

Original Poster
Rep: Reputation: 16
Let me try again and explain,what i said before it was about proxy cheker.That works.
Ok,this Proxifier intercepts all connections made to the net.So if strat my program,and then proxifier,and lets say i open a webpage linuxquestions.org.The page will be intercepted by Proxifier,and my program prints whats is happening(the page will not open in browser,gives error):
Code:
You are connected !!!

-> Received 3 bytes (1st packet)
NO AUTHENTICATION REQUIRED !
<- Sending 2 bytes (1st packet)
-> Received 10 bytes (2nd packet)
Size of packet: 10
Version: 5
Connection type: 1
Address type: 1
Destination adrress: 209.34.245.100
Destination port: 80
<- Sending 10 bytes (2nd packet)
CONNETING TO :209.34.245.100 80
The proxifier display is this:
Code:
opera.exe - 209.34.245.100:80 open
Btw,i get error in the function only when i use that proxy checker,so lets forget about it
Now,when i test with the debugger i saw that it remains block after i call connect(),it just waits for something,after a few seconds after printing thoose messages with CONNETING TO :209.34.245.100 80 It gives me an error "Invalid argument" at coonect() then it retries again to connect and error again,so it continuosly tries to connect but gives error. I' really confusing you i know.Sorry.

edit: looking better i noticed that the first error is again Result too large and then it gives Invalid argument
edit2: ussing a separate functiin like yours fillAddr it returns -1 but says No Error.Just like at the begining

Last edited by vbx_wx; 02-05-2011 at 12:32 PM.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Cannot connect using VNC , error "error opening security policy file /usr/X11R6/lib/" wmasry Linux - Newbie 5 01-18-2012 12:58 PM
Error: Could not connect to the Server divyashree SUSE / openSUSE 3 10-12-2010 09:50 AM
the error i get when trying to connect RedEyez Linux - Networking 10 04-18-2007 10:31 AM
ldap_start_tls: Connect error (-11) guy_ripper Linux - Networking 1 12-04-2006 06:17 AM
Socket error on Connect mdimanna Programming 2 06-24-2005 10:28 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 12:32 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration