为什么我不能通过实际的公共IP连接到服务器?

时间:2023-01-07 22:45:36

I am new in network programming and I try to do echo client and server. It works properly via localhost (127.0.0.1) and 192.168.1.35, but doesn't via my actual IP. So it's impossible to connect to my server across the Internet. However, I checked it in my local network and it worked.
You can try client. If connection is done, client display an appropriate message. There are two clients. For IP 192.168.1.35 and for my actual IP, which I can get by such and similar services. There are several libs which should be located in the same directory as exe.

我是网络编程的新手,我试着做echo客户端和服务器端。它通过localhost(127.0.0.1)和192.168.1.35正常工作,但不是通过我的实际IP。因此,在互联网上连接我的服务器是不可能的。但是,我在我的本地网络中检查了它,它起作用了。你可以试着客户。如果连接完成,客户机将显示一个适当的消息。有两个客户。对于IP 192.168.1.35和我的实际IP,我可以通过这样和类似的服务获得。有几个libs应该位于exe的同一个目录中。

And one more question. What does my server display by these lines?

和一个问题。我的服务器通过这些线显示什么?

tcp::endpoint ep = *iter++;
std::cout << ep << std::endl;

The output is:

的输出是:

[fe80::5100:812f:ad7c:a6dc%13]:0
192.168.1.35:0

I just wanted to get my IP and the second one is an IP, though it is local. But what is first one?
Thank you!

我只是想获得我的IP,第二个是IP,虽然它是本地的。但第一个是什么?谢谢你!

I use MSVS 2013, Boost::Asio, Windows 7.
Here is the code:
server.cpp

我使用MSVS 2013, Boost::Asio, Windows 7。这里是代码:server.cpp。

#ifdef WIN32
#define _WIN32_WINNT 0x0501
#include <stdio.h>
#endif

#include <iostream>

#include <boost/bind.hpp>
#include <boost/asio.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
using namespace boost::asio;
using namespace boost::posix_time;
using boost::system::error_code;

io_service service;
size_t read_complete(char * buff, const error_code & err, size_t bytes) {
    if (err) return 0;
    bool found = std::find(buff, buff + bytes, '\n') < buff + bytes;
    // we read one-by-one until we get to enter, no buffering
    return found ? 0 : 1;
}

void handle_connections() {
    ip::tcp::acceptor acceptor(service, ip::tcp::endpoint(ip::tcp::v4(), 8001));
    char buff[1024];
    while (true) {
        ip::tcp::socket sock(service);
        acceptor.accept(sock);
        int bytes = read(sock, buffer(buff),
            boost::bind(read_complete, buff, _1, _2));
        std::string msg(buff, bytes);
        sock.write_some(buffer(msg));
        sock.close();
    }
}

int main(int argc, char* argv[]) {
    using boost::asio::ip::tcp;
    boost::asio::io_service io_service;
    tcp::resolver resolver(io_service);
    tcp::resolver::query query(boost::asio::ip::host_name(), "");
    tcp::resolver::iterator iter = resolver.resolve(query);
    tcp::resolver::iterator end; // End marker.
    while (iter != end)
    {
        tcp::endpoint ep = *iter++;
        std::cout << ep << std::endl;
    }
    handle_connections();
}

client.cpp

client.cpp

#ifdef WIN32
#define _WIN32_WINNT 0x0501
#include <stdio.h>
#endif


#include <boost/thread.hpp>
#include <boost/bind.hpp>
#include <boost/asio.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
using namespace boost::asio;
using boost::system::error_code;
io_service service;

size_t read_complete(char * buf, const error_code & err, size_t bytes) {
    if (err) return 0;
    bool found = std::find(buf, buf + bytes, '\n') < buf + bytes;
    // we read one-by-one until we get to enter, no buffering
    return found ? 0 : 1;
}

//ip::tcp::endpoint ep(ip::address::from_string("127.0.0.1"), 8001);
ip::tcp::endpoint ep(ip::address::from_string("192.168.1.35"), 8001);
void sync_echo(std::string msg) {
    msg += "\n";
    ip::tcp::socket sock(service);
    sock.connect(ep);
    sock.write_some(buffer(msg));
    char buf[1024];
    int bytes = read(sock, buffer(buf), boost::bind(read_complete, buf, _1, _2));
    std::string copy(buf, bytes - 1);
    msg = msg.substr(0, msg.size() - 1);
    std::cout << "server echoed our " << msg << ": "
        << (copy == msg ? "OK" : "FAIL") << std::endl;
    sock.close();
}

int main(int argc, char* argv[]) {
    // connect several clients
    char* messages[] = { "John says hi", "so does James",
        "Lucy just got home", "Boost.Asio is Fun!", 0 };
    boost::thread_group threads;
    for (char ** message = messages; *message; ++message) {
        threads.create_thread(boost::bind(sync_echo, *message));
        boost::this_thread::sleep(boost::posix_time::millisec(100));
    }
    threads.join_all();

    char ch;
    std::cin >> ch;
}

2 个解决方案

#1


1  

If you want to connect to your PC from outside LAN to port 8001 you have to open this port in router and tell your router what to do with the incoming connection on port 8001. If your router public IP is 92.168.1.35 and you are listening on local PC 192.168.1.35 on port 8001, then you have to open your router configuration page in Web browser, go to Port Forwarding/ Port Triggering and establish a forwarding of port 8001 of your router to 192.168.1.35 8001. Also make sure your server listens on 0.0.0.0 ( INADDR_ANY in C code) not on your LAN interface.

如果你想从局外局域网连接到端口8001,你必须在路由器上打开这个端口,并告诉你的路由器如何处理端口8001上的连接。如果您的路由器公共IP是92.168.1.35,您在端口8001上监听本地PC 192.168.1.35,那么您必须在Web浏览器中打开路由器配置页面,转到端口转发/端口触发,并建立路由器端口8001的转发到192.168.1.358001。还要确保您的服务器在LAN接口上不监听0.0.0.0 (INADDR_ANY在C代码中)。

After this you can check if application is listening on port 8001:

在此之后,您可以检查应用程序是否监听端口8001:

sudo netstat -anlpl | grep 8001

#2


1  

I just wanted to get my IP and the second one is an IP, though it is local. But what is first one?

我只是想获得我的IP,第二个是IP,虽然它是本地的。但第一个是什么?

The first one is your ipv6 address

第一个是ipv6地址。

The reason it doesn't work "externally" is likely routing or firewalling.

它不能在“外部”工作的原因可能是路由或防火墙。

Make sure port 13 8001 is routed to your machine and not blocked.

确保端口138001被路由到您的机器,而不是被阻塞。

#1


1  

If you want to connect to your PC from outside LAN to port 8001 you have to open this port in router and tell your router what to do with the incoming connection on port 8001. If your router public IP is 92.168.1.35 and you are listening on local PC 192.168.1.35 on port 8001, then you have to open your router configuration page in Web browser, go to Port Forwarding/ Port Triggering and establish a forwarding of port 8001 of your router to 192.168.1.35 8001. Also make sure your server listens on 0.0.0.0 ( INADDR_ANY in C code) not on your LAN interface.

如果你想从局外局域网连接到端口8001,你必须在路由器上打开这个端口,并告诉你的路由器如何处理端口8001上的连接。如果您的路由器公共IP是92.168.1.35,您在端口8001上监听本地PC 192.168.1.35,那么您必须在Web浏览器中打开路由器配置页面,转到端口转发/端口触发,并建立路由器端口8001的转发到192.168.1.358001。还要确保您的服务器在LAN接口上不监听0.0.0.0 (INADDR_ANY在C代码中)。

After this you can check if application is listening on port 8001:

在此之后,您可以检查应用程序是否监听端口8001:

sudo netstat -anlpl | grep 8001

#2


1  

I just wanted to get my IP and the second one is an IP, though it is local. But what is first one?

我只是想获得我的IP,第二个是IP,虽然它是本地的。但第一个是什么?

The first one is your ipv6 address

第一个是ipv6地址。

The reason it doesn't work "externally" is likely routing or firewalling.

它不能在“外部”工作的原因可能是路由或防火墙。

Make sure port 13 8001 is routed to your machine and not blocked.

确保端口138001被路由到您的机器,而不是被阻塞。