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

Why can't I connect to server via actual public IP?

本文关键字:IP 连接 服务器 为什么      更新时间:2023-10-16

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

还有一个问题。我的服务器通过这些行显示什么?

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

输出为:

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

我只是想得到我的IP,第二个是IP,尽管它是本地的。但第一个是什么
非常感谢。

我使用MSVS 2013,Boost::Asio,Windows 7。
这是代码:
服务器.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();
}

客户端.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;
}

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

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

sudo netstat -anlpl | grep 8001

我只是想得到我的IP,第二个是IP,尽管它是本地的。但第一个是什么?

第一个是你的ipv6地址

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

确保端口138001已路由到您的机器且未被阻塞。