1

I want to understand more about sending data over internet. I have been searching A LOT everywhere but nothing helped... I'm using MinGw and please dont say that i have to change my developer program. So far i made this from what I found: And it work great but only for my local network. Can anyone tell me how i can do the same thing only over the internet?

using namespace std;
#pragma once
#include <iostream>
#include "WinSock2.h"
const int STRLEN = 256;

class Socket
{
    protected:
        WSADATA wsaData;
        SOCKET mySocket;
        SOCKET myBackup;
        SOCKET acceptSocket;
        sockaddr_in myAddress;
    public:
        Socket();
        ~Socket();
        bool SendData( char* );
        bool RecvData( char*, int );
        void CloseConnection();
        void GetAndSendMessage();
};

class ServerSocket : public Socket
{
    public:
        void Listen();
        void Bind( int port );
        void StartHosting( int port );
};

class ClientSocket : public Socket
{
    public:
        void ConnectToServer( const char *ipAddress, int port );
};


Socket::Socket()
{
    if( WSAStartup( MAKEWORD(2, 2), &wsaData ) != NO_ERROR )
    {
        cerr<<"Socket Initialization: Error with WSAStartup\n";
        system("pause");
        WSACleanup();
        exit(10);
    }

    //Create a socket
    mySocket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );

    if ( mySocket == INVALID_SOCKET )
    {
        cerr<<"Socket Initialization: Error creating socket"<<endl;
        system("pause");
        WSACleanup();
        exit(11);
    }

    myBackup = mySocket;
}

Socket::~Socket()
{
    WSACleanup();
}

bool Socket::SendData( char *buffer )
{
    send( mySocket, buffer, strlen( buffer ), 0 );
    return true;
}

bool Socket::RecvData( char *buffer, int size )
{
    int i = recv( mySocket, buffer, size, 0 );
    buffer[i] = '\0';
    return true;
}

void Socket::CloseConnection()
{
    //cout<<"CLOSE CONNECTION"<<endl;
    closesocket( mySocket );
    mySocket = myBackup;
}

void Socket::GetAndSendMessage()
{
    char message[STRLEN];
    cin.ignore();//without this, it gets the return char from the last cin and ignores the following one!
    cout<<"Send > ";
    cin.get( message, STRLEN );
    SendData( message );
}

void ServerSocket::StartHosting( int port )
{
     Bind( port );
     Listen();
}

void ServerSocket::Listen()
{
    //cout<<"LISTEN FOR CLIENT..."<<endl;

    if ( listen ( mySocket, 1 ) == SOCKET_ERROR )
    {
        cerr<<"ServerSocket: Error listening on socket\n";
        system("pause");
        WSACleanup();
        exit(15);
    }

    //cout<<"ACCEPT CONNECTION..."<<endl;

    acceptSocket = accept( myBackup, NULL, NULL );
    while ( acceptSocket == SOCKET_ERROR )
    {
        acceptSocket = accept( myBackup, NULL, NULL );
    }
    mySocket = acceptSocket;
}

void ServerSocket::Bind( int port )
{
    myAddress.sin_family = AF_INET;
    myAddress.sin_addr.s_addr = inet_addr( "0.0.0.0" );
    myAddress.sin_port = htons( port );

    //cout<<"BIND TO PORT "<<port<<endl;

    if ( bind ( mySocket, (SOCKADDR*) &myAddress, sizeof( myAddress) ) == SOCKET_ERROR )
    {
        cerr<<"ServerSocket: Failed to connect\n";
        system("pause");
        WSACleanup();
        exit(14);
    }
}

void ClientSocket::ConnectToServer( const char *ipAddress, int port )
{
    myAddress.sin_family = AF_INET;
    myAddress.sin_addr.s_addr = inet_addr( ipAddress );
    myAddress.sin_port = htons( port );

    //cout<<"CONNECTED"<<endl;

    if ( connect( mySocket, (SOCKADDR*) &myAddress, sizeof( myAddress ) ) == SOCKET_ERROR )
    {
        cerr<<"ClientSocket: Failed to connect\n";
        system("pause");
        WSACleanup();
        exit(13);
    } 
}

int main()
{
    int choice;
    int port = 666;
    //char *ipAddress = "127.0.0.1";
    string ipAddress;
    bool done = false;
    char recMessage[STRLEN];
    char sendMessage[STRLEN];
    cout<<"1) Host server"<<endl;
    cout<<"2) Join server"<<endl;
    cout<<"3) Quit"<<endl;
    cin>>choice;
    if ( choice == 3 )
        exit(0);
    else if ( choice == 2 )
    {
        //Client
        cout<<"Enter an IP address, 127.0.0.1 is the loopback address"<<endl;
        cin>>ipAddress;
        ClientSocket sockClient;
        cout<<"ATTEMPTING TO CONNECT..."<<endl;
        sockClient.ConnectToServer( ipAddress.c_str(), port );
        //Connected
        while ( !done )
        {     
            sockClient.GetAndSendMessage();
            cout<<"\t--WAIT--"<<endl;
            sockClient.RecvData( recMessage, STRLEN );
            cout<<"Recv > "<<recMessage<<endl;
            if ( strcmp( recMessage, "end" ) == 0 ||
                        strcmp( sendMessage, "end" ) == 0 )
            {
                done = true;
            }
        }
        sockClient.CloseConnection();
    }
    else if ( choice == 1 )
    {
        //SERVER
        ServerSocket sockServer;
        cout<<"HOSTING..."<<endl;
        sockServer.StartHosting( port );
        //sockServer.StartHosting( port );
        //Connected
        while ( !done )
        {
            cout<<"\t--WAIT--"<<endl;
            sockServer.RecvData( recMessage, STRLEN );
            cout<<"Recv > "<<recMessage<<endl;
            sockServer.GetAndSendMessage();
            if ( strcmp( recMessage, "end" ) == 0 || strcmp( sendMessage, "end" ) == 0 )
            {
                done = true;
            }
        }
    }
}

Thanks to all who responded but, you gave me a lot to read when i just asked what part of the code should be changed so i can use the internet. Obviously I cant understand half of what is written there. Still nothing helped.

bluish
  • 26,356
  • 27
  • 122
  • 180
user1496857
  • 51
  • 1
  • 5

3 Answers3

2

If you want to use sockets over the internet and you want your application to be usable on every network setting, including NAT, you will have to use a TCP Holepunch called technique (or UDP holepunching may also fit). I think your approach is not working because there is some NAT between your endpoints, so socket connections fail.

I suggest to investigate on NAT. Peer-to-Peer Communication Across Network Address Translators

And this discussion here on SO

Community
  • 1
  • 1
Mare Infinitus
  • 8,024
  • 8
  • 64
  • 113
  • Holepunching is tricky. I say - just do an explicitly open port in the NAT. That is, once the OP knows it's a NAT. – Seva Alekseyev Jul 02 '12 at 19:15
  • And as he did not provide information about his different endpoints, perhaps this will not be enough. You are right, it is tricky. Even with some knowledge about TCP/IP – Mare Infinitus Jul 02 '12 at 19:17
0

What is it that you don't understand? I see the code and it's binding to a local socket and then you connect to it with a client. You can do this over the internet as well but what is it that you aren't understanding about the process? I'm afraid you may need to start learning the basics of TCP/IP before trying to write socket code. It's like trying to start out learning engineering by building a space shuttle.

Rocky Pulley
  • 22,531
  • 20
  • 68
  • 106
  • Can u then please modify the code or at least tell me where to "start learning the basics of TCP/IP" – user1496857 Jul 02 '12 at 19:12
  • It is not that I cannot understand your arguments, but I do not believe this will help the OP. But thanks for posting the source – Mare Infinitus Jul 02 '12 at 19:12
  • @user1496857 you should read the doc in the link in my answer. if you come across concepts you did not already know, you will have good points to start learning – Mare Infinitus Jul 02 '12 at 19:15
  • 2
    @user1496857 - In my opinion, and based on my experience, if you want to learn the basics of TCP/IP, you need to get a textbook. You won't learn that just by tinkering. Yes, learning involves tinkering, but these two are not the same. – luis.espinal Jul 02 '12 at 19:16
  • 1
    I agree, you really need to get a book on TCP/IP if you really want to know what you are doing. You might be able to hack something up by tinkering but you will have no idea what is going on and you should not be writing socket code if you don't know what you are doing. – Rocky Pulley Jul 02 '12 at 19:22
0

The ability to host a service that's visible from the Internet is very dependent on the type of the Internet connection you've got. If you're behind a NAT, you'll need to set up a NAT port forwarding. If your IP address is dynamic, you'll need to know your publicly available IP address (try http://www.whatismyip.com/).

Seva Alekseyev
  • 59,826
  • 25
  • 160
  • 281
  • I would like the program to run on almost every pc, even if they have port fowarding and even if they have not. – user1496857 Jul 02 '12 at 19:16
  • @user1496857 That's a laudable goal, but it's very obvious that you don't have the knowledge for that. Please don't take that personally, we've all been there at some point. And the thing is, it's a lot of knowledge - more than a single SO answer can reasonably fit. – Seva Alekseyev Jul 02 '12 at 19:20