我一直堅持這個問題的年齡...連接到外部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中,不管是什麼...... –