我被这个问题困扰了很久...
所以我使用 BSD 套接字/Winsock 2 TCP 编写了一个多人游戏。我的服务器已启动并正常工作,我可以在本地连接到它(通过填写我自己的外部 ip 间接连接)。一切似乎都很好。我在 canyouseeme.org 上测试了我的 ip 和服务器端口是否正确地进行了端口转发,并且它运行良好。然后我把我的客户端发给了一个 friend ,通过连接服务器来测试它,但它一直失败。我希望他能连接上,但我在服务器端看不到任何东西(而 canyouseenme.org 甚至作为无效客户端弹出)。我不明白,我是否必须为 TCP 中的外部连接做一些特殊的事情?
这是我的连接函数:
int CConnectSocket(CSocket s, unsigned short port, char* ipaddress)
{
SOCKADDR_IN target;
target.sin_family = AF_INET;
target.sin_port = htons(port);
target.sin_addr.s_addr = htonl(inet_addr(ipaddress));
if (connect(s, (SOCKADDR*)&target, sizeof(target)) == SOCKET_ERROR)
{
if (WSAGetLastError() == WSAEISCONN)
return CTCP_DONE;
else if (WSAGetLastError() != WSAEWOULDBLOCK && WSAGetLastError() != WSAEALREADY)
{
strcpy(inerr, "CConnectSocket: Failed to connect the socket. Error ");
char f[6];
sprintf(f, "%d", WSAGetLastError());
strcat(inerr, f);
return CTCP_ERROR;
}
return CTCP_WAIT;
}
return CTCP_DONE;
}
我一直循环此函数,直到返回 CTCP_DONE(意味着我已连接)。我的 friend 报告说他超时了(所以它返回 CTCP_WAIT 的时间太长了)。同样,我确定客户端是错误的,因为我的服务器能够接受来自 canyouseeme.org 的外部连接。我填写的IP地址和端口有效,因为我可以在本地连接。如果我更改端口,本地连接将不再有效(证明这是一个正确的参数)。更改 IP 确实会产生相同的结果。
感谢您的帮助!希望我能解决这个问题并开始多人游戏。
编辑
void CEngine::CSetSockAddr(CSockAddr* address, unsigned short port, char* ipaddress)
{
memset(address, 0, sizeof(CSockAddr));
address->sin_family = AF_INET;
address->sin_port = htons(port);
address->sin_addr.s_addr = htonl(inet_addr(ipaddress));
}
这是我的套接字地址函数。当我删除 htonl 函数时,它在我 friend 这边工作,但不再在我这边工作(我也托管服务器)。顺便说一句,我的 friend 使用的是 XP,但由于我要求使用 2.2 WinSock,所以应该没有问题。至少我希望 WinSock 的设置函数在返回 true 时保证 2.2 的实现。
编辑 2
大家好,
我现在已经准备好一切并开始工作了。似乎如果我添加 htonl,我可以作为主机连接到外部 IP,而不是连接到环回 127.0.0.0.1 或类似的东西。所以现在我想知道,如何检测我是否连接到我托管的服务器?那将是一个不错的把戏。祝大家新年快乐!
最佳答案
如果没有控制台很难帮助你......但你可以和你的 friend 谈谈并试试这个:
- 从您 friend 的 PC 上对您的服务器执行 ping 操作。
- 如果您收到答复,请使用 tracert 或 traceroute 找出问题所在
- 您 friend 的路线模型是什么?可能它有一个系统事件日志,您可以在其中检查被拒绝的连接。
祝你好运!
关于c++ - 连接到外部 IP 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27623133/