【问题标题】:C++ SFML Networking: Can't Establish a TCP ConnectionC++ SFML 网络:无法建立 TCP 连接
【发布时间】:2016-12-30 21:03:02
【问题描述】:

第二次更新:ok, here's the wireshark results for what happens when I try to connect to a friend with this program, and it fails. I've tried to remove his info, that's all the redacted lines.

更新:这适用于我本地网络上的所有计算机,使用本地 IP 地址。现在,当我尝试使用公共 IP 地址连接到远程计算机时,它出现了问题。大约 20 秒后,客户端收到“无法连接”,然后是“错误号 3”,其中 3 是 sfml 提供的错误代码。

我只想知道如何建立远程连接。我查看了其他几个似乎与我相同的示例,并且它们有效。

编辑:我将端口 5000 转发到路由器上的计算机,并将该端口连同我的公共 IP 地址一起提供给客户端,以防万一。这是我设置http://i.imgur.com/Q8Kyu1E.png 的规则的屏幕截图。我还尝试完全禁用 Windows 防火墙,结果相同。

以下是代码的相关部分:

#include <SFML/System.hpp>
#include <SFML/Network.hpp>
#include <SDL.h>
#include <SDL_image.h>
#include <SDL_ttf.h>
#include <vector>
#include <string>
#include "font.h"
#include "overhead.h"
#include "texture.h"
#include <iostream>

void render(Overhead &overhead, SDL_Rect *clip, Texture &texture, double angle, SDL_Point *centre, SDL_RendererFlip flip) {
    SDL_Rect render = { texture.textData.x, texture.textData.y, texture.textData.w, texture.textData.h };
    SDL_RenderCopyEx(overhead.renderer, texture.texture, clip, &render, angle, centre, flip);
}

void close(Overhead &overhead, Font &font) {
    TTF_CloseFont(font.font);
    font.font = NULL;
    overhead.closeOverhead();
}

int main(int argc, char* args[]) {
    sf::Packet packet;
    sf::TcpSocket peer;
    sf::TcpListener listener;
    unsigned short port;
    std::string ip;
    sf::IpAddress ipaddress;
    char host;
    std::cout << "host (y/n): ";
    std::cin >> host;
    if (host == 'y') {
        std::cout << "port number to listen on: ";
        std::cin >> port;
        std::cout << "IP Address for local connection: " << sf::IpAddress::getLocalAddress() << std::endl;
        std::cout << "IP Address for remote connection: " << sf::IpAddress::getPublicAddress() << std::endl;
        if (listener.listen(port) != sf::Socket::Done)
            std::cout << "listener error" << std::endl;
        if (listener.accept(peer) == sf::Socket::Done)
            std::cout << "connection successful" << peer.getRemoteAddress() << std::endl;
    }
    else {
        std::cout << "port number to connect to: ";
        std::cin >> port;
        std::cout << "you chose port number " << port << std::endl;
        std::cout << "ip address to connect to: ";
        std::cin >> ip;
        ipaddress = ip;
        sf::Socket::Status status = peer.connect(ipaddress, port);
        if (status != sf::Socket::Done) {
            std::cout << "cannot connect" << std::endl;
            std::cout << "error number: " << status;
        }
        else if (status == sf::Socket::Done)
            std::cout << "connection successful" << std::endl;
    }
    //other stuff
    peer.disconnect();
    close(overhead, font);
    return 0;
}

【问题讨论】:

  • 你在客户端输入的是什么IP地址?含义是 90.50.90.50 还是 192.168.1.100 类型?
  • 它的类型为 90.50.90.50,即。公共 IP 地址。我刚刚尝试将代码切换为使用本地 IP 地址(使用 sf::IpAddress::getLocalAddress())并且它确实有效,尽管我认为这对于连接到我家以外的人不是很有用网络。
  • “无法连接”不是有用的信息。它只是您的应用程序为响应大约十几种可能的故障条件中的任何一种而打印的文本字符串。您至少需要打印errno,或者最好打印strerror() 的结果。或致电perror()。在您提供该信息之前,您的问题是无法回答的。
  • 我不知道如何为此实现 strerror() 或 perror() 或 errno,但我确实在我的更新版本中打印了 sfml 提供的状态消息。它打印 3
  • 如果您看这里,3 表示已断开连接。 blaxpirit.github.io/crsfml/api/SF/Socket/Status.html

标签: c++ network-programming sfml


【解决方案1】:

我在尝试在本地网络上托管服务器时遇到了完全相同的问题。看来,就像我的一样,您的路由器不允许 NAT Loopback,即通过本地网络访问您的外部 IP(有关 NAT Loopback 的更多详细信息,请参阅this link)。
事实上,您可以使用公共 IP 地址从位于本地网络之外的客户端访问主机,但如果您想从本地网络内部访问主机,则必须使用本地地址。

【讨论】:

  • 哦,我没有意识到这一点。谢谢。
  • 嗯,实际上它不适用于我的网络之外的计算机。正如你所说,它适用于我网络内部的计算机。
  • 我只是尝试运行 SFML 最新版本提供的套接字示例:我将适当的端口转发到我的计算机并尝试使用本地网络之外的另一台计算机通过 TCP ping 它。连接已成功接受...
  • 您应该尝试以与您的程序相同的方式运行此示例程序,并查看在尝试连接时是否出现错误。
  • 感谢您的建议,我没有意识到那里有。我的一个朋友收到了一条“已连接”的消息,但我没有看到任何关于我的信息,而且他没有收到如果事情正常运行他会收到的后续消息。其他两个尝试联系的朋友(我也尝试联系他们)甚至没有走到那一步。这真的很奇怪也很烦人,因为据我所知,我们所做的一切都是正确的。我将尝试下载 Wireshark,以便查看可能出现的问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-28
  • 1970-01-01
  • 1970-01-01
  • 2012-02-23
相关资源
最近更新 更多