0

this is probably trivial but I need help in making my server listen on my ISP IP address rather than the localhost in my client-server messager program. My server and client is as follows.

server

/*Server */
#define _WIN32_WINNT 0x501
#include <iostream>
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
using namespace std;

const int winsock_version = 2;
#define PORT "3490"
#define MAX_NUM_CONNECTIONS 10

int main(void){

    WSADATA wsadata;

    if (WSAStartup(MAKEWORD(winsock_version,0),&wsadata) == 0){
        cout<<"-WSAStartup Initialized." << endl;

        struct addrinfo hints,*res;
        int sock_fd;

        memset(&hints,0,sizeof hints);
        hints.ai_family = AF_UNSPEC;
        hints.ai_socktype = SOCK_STREAM;
        hints.ai_flags = AI_PASSIVE;

        if (getaddrinfo(NULL,PORT,&hints,&res) != 0){
            cout<<"-Call to getaddress was unsucceful." << endl;
        }

        if( (sock_fd = socket(res->ai_family,res->ai_socktype,res->ai_protocol)) == -1){
            cout<<"-Unable to Create socket." << endl;
        }

        if ( (bind(sock_fd, res->ai_addr, res->ai_addrlen)) != -1 ){
            cout<<"-binding successful." << endl;
        }

        if ( (listen(sock_fd,MAX_NUM_CONNECTIONS)) != -1){
            cout<<"-Listening for incoming connections." << endl;
        }
        //-------------------------------------------------------------

        struct sockaddr_storage incming_info;
        socklen_t sin_size;
        sin_size = sizeof incming_info;

        int new_fd;

        new_fd = accept(sock_fd, (struct sockaddr*)&incming_info,&sin_size);
        if (new_fd == -1){
            cout<<"-Accepting error." << endl;
        }
        if(new_fd == INVALID_SOCKET){
            cout<<"-INVALID SOCKET ERROR." << endl;
        }
        char buffer[128];
        while(true){
            int ret_val;

            ret_val = recv(new_fd,buffer,sizeof(buffer),0);
            if(ret_val == -1){
                cout<<"Receiving Error." << endl;
                break;
            }else if(ret_val == 0){
                cout<<"Connection has been closed!." << endl;
                break;
            }else{
                cout<<"Server: " << buffer<< endl;
            }
        }
        cout<<"-Closing connection" << endl;
        closesocket(new_fd);

    }else{
        cout<<"-WSAStartup Initialization failed." << endl;
        if(WSACleanup()!=0){
            cout<<"-WSACleanup Successful." << endl;
        }else{
            cout<<"-WSACleanup Failed." << endl;
        }
    }
    return 0;
}

client

/*client*/
#define _WIN32_WINNT 0x501
#include <iostream>
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
using namespace std;

#define PORT "3490"
#define SERVER "localhost"
const int winsockVersion = 2;


int main(void){

    WSADATA wsadata;
    if ( (WSAStartup(MAKEWORD(2,0),&wsadata)) == 0){
        cout<<"-WSAStartup Initialized." << endl;

        struct addrinfo hints, *res;
        int sockfd;

        memset(&hints,0,sizeof hints);
        hints.ai_family = AF_UNSPEC;
        hints.ai_socktype = SOCK_STREAM;

        if (getaddrinfo(SERVER,PORT,&hints,&res) != 0){
            cout<<"-getaddrinfo unsuccessful." << endl;
        }

        if ( (sockfd = socket(res->ai_family,res->ai_socktype,res->ai_protocol)) == -1 ){
            cout<<"-Unable to create socket." << endl;
        }

        if ( (connect(sockfd,res->ai_addr,res->ai_addrlen)) != -1 ){
            cout<<"-Connection Established." << endl;
        }

        cout<<"-Client connecting to: " << res->ai_addr << endl;

        while(true){
            string text_buff;
            cout<<"Enter text: ";
            getline(cin,text_buff);
            if( (send(sockfd,text_buff.c_str(),text_buff.length()+1,0)) != -1 ){
                cout<<"-text_buff sent!." << endl;
            }

        }

    }else{
        cout<<"-WSAStartup Initialization failed." << endl;
        if(WSACleanup()!=0){
            cout<<"-WSACleanup Successful." << endl;
        }else{
            cout<<"-WSACleanup Failed." << endl;
        }
    }

    return 0;
}

I know how (i think) to specify the client in order to make it connect to my IP address XXX.XX.XXX.XX by changing the SERVER in client.cpp, But I'm not sure how to get the server to listen on this?.

silent
  • 2,836
  • 10
  • 47
  • 73

2 Answers2

1

Take a look here:

C++ strange socket data

This line:

addrinfo.sin_addr.s_addr = INADDR_ANY;

specifies any address. See here:

for getaddrinfo if you want to use a specific IP or a hostname instead of any.

Community
  • 1
  • 1
icyrock.com
  • 27,952
  • 4
  • 66
  • 85
  • yes I've tried setting my IP address into getaddrinfo but when I run the server I get an error in accept()ing, and this leads to the program closing the connection. – silent Nov 23 '10 at 04:29
  • +1 for the INADDR_ANY. @sil3nt: if you have no problem with listening to all networks you have, you can use INADDR_ANY. – default Nov 23 '10 at 08:26
  • @Default, still not working, I'll try doing this without getaddrinfo and pack everything by hand and see how it goes. – silent Nov 23 '10 at 12:21
  • 1
    I wrote a pretty extensive "tutorial" for winsock [here](http://stackoverflow.com/questions/2843277/c-winsock-p2p/2920787#2920787). See if that can help. (I use inaddr_any there as well) – default Nov 23 '10 at 12:25
  • 2
    @Default Thanks! @sil3nt I suggest you first try some sample that works (e.g. the link from the answer, Default's comments or just google it) and then work around it until you figure out how it works - much easier then starting on your own while still discovering the API. – icyrock.com Nov 24 '10 at 00:26
  • Thank you Default, that really helps, and yeahp will be looking into this more carefully. -cheers. – silent Nov 24 '10 at 01:20
0

getaddrinfo takes as first option the identity of the server - that could be a name you can lookup in the dns or an ip address.

when you specify null on your 'server' side it implies localhost, on the client you specifically set local host.

The MSDN doc

The function your using is going to report back a list of possible addrinfo, you happen to be binding the first one.
At the moment you are hinting you want a stream. the rest is up to the resolver, so you will get stuff on all ips for localhost (loopback, wireless, ether, wan), and any port, on ipv4 and ipv6.

You need to be more specific about your hints, or perhaps skip this function and specify the port and address directly.

Greg Domjan
  • 13,943
  • 6
  • 43
  • 59
  • Hello, yes i tried setting `getaddrinfo` to my IP address, without having AI_PASSIVE. But when I do this I get an error when accept()ing, which leads to an error in creating a socket and receiving, and the program closes the connection after that. This all happens as soon as I just run the server. – silent Nov 23 '10 at 04:27
  • bind() is failing, I don't understand why. – silent Nov 23 '10 at 05:54