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

时间:2014-04-10 09:25:18

标签: c++ sockets tcp network-programming boost-asio

我是网络编程的新手,我尝试做echo客户端和服务器。它通过localhost(127.0.0.1)和192.168.1.35正常工作,但不是通过我的实际IP。因此,无法通过Internet连接到我的服务器。但是,我在我的本地网络中查看了它并且它有效 您可以尝试client。如果连接完成,客户端将显示相应的消息。有两个客户。对于IP 192.168.1.35和我的实际IP,我可以通过such和类似的服务获得。有几个库应与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 这是代码:
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

#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 个答案:

答案 0 :(得分:1)

  

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

第一个是你的ipv6地址

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

确保端口 13 8001路由到您的计算机而不会被阻止。

答案 1 :(得分:1)

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

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

sudo netstat -anlpl | grep 8001