我一直坚持这个问题的年龄...连接到外部IP失败
所以我编码与多人使用BSD插座/ Winsock 2 TCP的游戏。我的服务器已启动并正在运行,我可以在本地连接到它(间接地通过填写我自己的外部IP)。一切似乎都很好。我使用canyouseeme.org进行了测试,无论我的IP和服务器端口是否正确转发端口,并且完全正常工作。然后,我将我的客户端发送给朋友,通过连接到服务器进行测试,并且一直失败。我期望他能够连接,但我在服务器端看不到任何东西(虽然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(意思是我连)我一直循环这个功能。我的朋友报告他超时(所以它返回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函数时,它在我的朋友那边工作,但不再在我身边(我也托管服务器)。我的朋友BTW使用XP,但因为我打电话使用2.2 WinSock应该没有问题。至少我希望如果WinSock的设置函数返回true,它将保证2.2实现。
EDIT 2
好家伙,
我已经得到了一切了,现在的工作。看来,如果我添加htonl我可以作为主机与外部IP连接,而不是连接到环回127.0.0.0.1或者那样。所以现在我想知道,如何检测我是否连接到我托管的服务器?这将是一个很好的窍门。新年快乐!
也许你的朋友有防火墙,阻止连接。 –
不可能他没有检查,而另一个朋友和人也发生了同样的情况......所以我不知道。 – user209347
我不确定,但不是已经按网络字节顺序返回的'inet_addr()'?如果是这样,那么放下'htonl()'。也就是说,有一个'FormatString()'函数可以用来将错误代码转换为文本(然后应该用来引发异常)。顺便说一句,你是否尝试连接不同的工具,如一个浏览器?远程讲HTTP,无关紧要,只是为了测试连接。最后,错误也可能在CSocket中,不管是什么...... –