【问题标题】:How do I make my server application use my IP address instead of localhost如何让我的服务器应用程序使用我的 IP 地址而不是 localhost
【发布时间】:2010-11-23 03:48:43
【问题描述】:

这可能是微不足道的,但我需要帮助来让我的服务器侦听我的 ISP IP 地址,而不是我的客户端-服务器消息程序中的本地主机。我的服务器和客户端如下。

服务器

/*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*/
#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;
}

我知道如何(我认为)通过更改 client.cpp 中的 SERVER 来指定客户端以使其连接到我的 IP 地址 XXX.XX.XXX.XX,但我不确定如何获取服务器来监听这个?

【问题讨论】:

    标签: c++ gcc networking client-server winsock


    【解决方案1】:

    看这里:

    C++ strange socket data

    这一行:

    addrinfo.sin_addr.s_addr = INADDR_ANY;
    

    指定任何地址。见这里:

    getaddrinfo 如果您想使用特定 IP 或主机名而不是任何主机名。

    【讨论】:

    • 是的,我尝试将我的 IP 地址设置为 getaddrinfo,但是当我运行服务器时,我在接受()时遇到错误,这会导致程序关闭连接。
    • +1 表示 INADDR_ANY。 @sil3nt:如果您在收听所有网络方面没有问题,您可以使用 INADDR_ANY。
    • @Default,还是不行,我会尝试不使用 getaddrinfo 并手动打包所有内容,看看效果如何。
    • 我为 winsock here 写了一个相当广泛的“教程”。看看能不能帮上忙。 (我在那里也使用 inaddr_any)
    • @Default 谢谢! @sil3nt 我建议您首先尝试一些有效的示例(例如,答案中的链接,默认的 cmets 或只是谷歌它)然后解决它,直到您弄清楚它是如何工作的 - 然后更容易自己开始,同时仍然发现API。
    【解决方案2】:

    getaddrinfo 将服务器的身份作为第一个选项 - 这可能是您可以在 dns 或 IP 地址中查找的名称。

    当您在“服务器”端指定 null 时,它意味着 localhost,在您专门设置本地主机的客户端上。

    The MSDN doc

    您使用的函数将报告可能的 addrinfo 列表,您恰好绑定了第一个。
    目前你暗示你想要一个流。其余的取决于解析器,因此您将在 localhost(环回、无线、以太网、WAN)的所有 ip 上以及 ipv4 和 ipv6 上的任何端口上获取内容。

    您需要更具体地提示您的提示,或者可能跳过此功能并直接指定端口和地址。

    【讨论】:

    • 您好,是的,我尝试将getaddrinfo 设置为我的 IP 地址,但没有使用 AI_PASSIVE。但是当我这样做时,我在接受()时出现错误,这导致创建套接字和接收时出错,然后程序关闭连接。这一切都在我刚刚运行服务器时发生。
    • bind() 失败,我不明白为什么。
    猜你喜欢
    • 2013-02-04
    • 1970-01-01
    • 1970-01-01
    • 2019-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-11
    相关资源
    最近更新 更多