【问题标题】:connecting to an IP address instead of localhost?连接到 IP 地址而不是 localhost?
【发布时间】:2010-11-24 06:05:37
【问题描述】:

这是我的第二次尝试,我编写了一个服务器应用程序,如下所示,它输出客户端发送的任何内容。我有一个 server.exe 版本,它使用INADDR_ANY 监听任何内容,完成后,如果我指定客户端连接到本地主机,我可以使用我的客户端并连接到服务器(一切正常)。

但是如果我使用自己的 IP 地址而不是 localhost 作为客户端,我无法连接到服务器?我不应该能够以这种方式连接到服务器吗?。

我使用了另一个 server.exe,它被硬编码以使用我的 IP 地址而没有 INADDR_ANY,但它无法 bind()listen() 传入连接。我对如何继续感到困惑。

(我在同一台机器上运行服务器和客户端,这是个问题吗?)

服务器

#include <iostream>
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
using namespace std;

#define PORT 3490
#define IP "118.93.0.164"
#define BACKLOG 10

const int winsockversion = 2;

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

        struct sockaddr_in serv;
        memset(&serv,0,sizeof serv);
        serv.sin_family = AF_INET;
        serv.sin_port = htons(PORT);
        serv.sin_addr.s_addr = inet_addr(IP);//INADDR_ANY;//inet_addr(IP);
        //---------------------------------------
        struct addrinfo serv_addrinfo;
        serv_addrinfo.ai_family = AF_INET;
        serv_addrinfo.ai_socktype = SOCK_STREAM;
        serv_addrinfo.ai_protocol = IPPROTO_TCP;
        serv_addrinfo.ai_addrlen = sizeof(serv);
        serv_addrinfo.ai_addr = (sockaddr*)&serv;


        //---------------------------------------
        SOCKET serv_con;
        serv_con = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
        if (serv_con != INVALID_SOCKET){
            cout<<"-Server Socket created." << endl;
        }

        if (bind(serv_con,serv_addrinfo.ai_addr,serv_addrinfo.ai_addrlen) != -1){
            cout<<"-Binding Successful." << endl;
        }

        if( listen(serv_con,BACKLOG) != -1){
            cout<<"-Listening for incoming connections." << endl;
        }
        //--------------------------------------------------------------------
        SOCKET recv_socket;
        struct sockaddr_in client_info;
        int client_info_size = sizeof(client_info);

        char *con_addr = inet_ntoa(client_info.sin_addr);




        recv_socket = accept(serv_con,(sockaddr*)&client_info,&client_info_size);

        if( recv_socket != INVALID_SOCKET ){
            cout<<"-Connection Established!. " << endl;
            cout<<"-Connected to: [" << con_addr << "] " << endl;
        //----------------------------------------------------------------------
            char buffer[80];
            int bytes_in;
            while(true){

                bytes_in = recv(recv_socket,buffer,sizeof(buffer),0);
                if ( bytes_in > 0 ){
                    cout<<"[" << con_addr << "]" << buffer << endl;
                }

                if (bytes_in == 0 ){
                    cout<<"[" << con_addr << "] has disconnected." << endl;
                    break;
                }
                if (bytes_in == -1 ){
                    cout<<"-Possible Abrupt disconnecton from [" << con_addr << "]" << endl;
                    break;
                }
            }

            closesocket(recv_socket);
            closesocket(serv_con);

        }

    }else{
        cout<<"-WSAStartup Initialization failed." << endl;
    }

    if( WSACleanup()!= -1){
        cout<<"-WSACleanp Successful." << endl;
    }

    WSAGetLastError();


    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 "118.93.0.164" // and 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;
}

【问题讨论】:

  • 在同一台机器上运行服务器和客户端绝对不是问题。我怀疑您使用的 IP 地址并不是您机器拥有的地址。你的服务器有公共地址吗?还是私人地址?您确定您提供的是 ipconfig 命令报告的 IP 地址吗?
  • 你是对的它不是我的机器IP地址它是我的ISP提供的IP地址。我通过 wifi 连接了多台计算机,我试图连接到我的外部 IP(如果这是我的 ISP 提供的 IP 地址的名称?)。
  • 如何连接到给定 IP 地址的 ISP 并解析服务器运行的本地地址? (抱歉,还不熟悉行话)。

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


【解决方案1】:

如果您有路由器,则必须设置Port forwarding。这实际上取决于您拥有哪种路由器,因此您必须查找特定的路由器。

您不能绑定到您的 ISP 的 IP 地址,因为您不拥有它(路由器拥有)。您必须 bind 到您的计算机实际拥有的 IP 地址,该地址可通过 Windows 中的 ipconfig /all 找到。然后确保将您的路由器中的服务器端口号的流量转发到您计算机拥有的内部 IP 地址。

【讨论】:

  • @Default,有没有这方面的指南或教程?,我希望能够自动完成,而无需手动完成。我已经阅读了关于 UPnP 的内容,有没有什么知名的地方可以让我找到它?任何起始位置将不胜感激。
  • 指南或教程是什么?用于端口转发?或者您希望能够编写您的服务器/客户端程序并自动绑定到互联网?因为据我所知,这是无法做到的,你必须告诉你的硬件当事情发生时该怎么做。您的路由器应该如何知道您在计算机 A 上而不是计算机 B 上是否有服务器?如果 A 和 B 都有一个用于端口 x 的服务器怎么办?那么路由器应该怎么做呢?这就是为什么您必须手动执行此操作的原因。
  • 您可能想知道其他程序是如何做到的。好吧,他们有一台正在侦听互联网的服务器(他们使用的服务器直接在互联网上[不在路由器后面],或者他们有端口转发)。然后,为了在计算机之间进行连接,他们连接到该服务器,然后在两台计算机之间“中继”信息。但这并不真正相关,只是琐事。
  • @sil3nt:你真的看到了吗,或者这只是一个很好的评论? :) 如果你不明白,我会尝试进一步解释。
  • @Default,不,我明白了,我只是想知道如何为了好玩而设置这样的东西。阿帕奇呢?大声笑。
【解决方案2】:

当您尝试连接回服务器时,您使用的是 localhost/127.0.0.1,还是您正在侦听的 IP 地址?

尝试连接到“localhost”可能会尝试使用您的程序未侦听的环回接口。我不是 100% 确定它在 Windows 中是如何工作的。

我能否问一个更重要的问题,可能会促使您更改设计:为什么要绑定到特定 IP(和 localhost)?

【讨论】:

  • 我的目标是编写一个简单的客户端-服务器聊天(更多的是在屏幕上发送和打印)程序,到目前为止它可以在我的本地网络上运行。我想要做的是让我网络之外的其他人使用我的 ISP 分配的 IP 地址连接到我的服务器应用程序。这真的是我想做的全部
【解决方案3】:

您可以尝试使用 cmd 从客户端 ping 到服务器 IP 以查看是否是连接问题。

另外,我认为是这样的

#define PORT "3490"

在客户端是错误的,因为端口应该是一个整数。

【讨论】:

  • 客户端正在使用 getaddrinfo,它需要这个。
猜你喜欢
  • 1970-01-01
  • 2012-02-12
  • 1970-01-01
  • 2013-01-30
  • 2019-01-15
  • 1970-01-01
  • 2020-05-09
  • 1970-01-01
  • 2023-04-05
相关资源
最近更新 更多