2011-08-26 31 views
0

我寫了一個簡單的聊天程序與客戶端和服務器。當我使用192.168.1.1或127.0.0.1這樣的本地IP時,該程序可以正常工作,但如果我嘗試使用我的互聯網IP,則無法工作。 我已關閉計算機上的防火牆,並且已將端口轉發到端口17000(嘗試了其他端口),但仍無法正常工作。 可能是什麼問題?C++簡單聊天不能使用我的IP地址

下面是客戶端的代碼:

#define _WINSOCK_ 
#include <WinSock2.h> 
#include <stdio.h> 
#pragma comment(lib, "ws2_32.lib") 
#define SERVER_ADDRESS "127.0.0.1" 
#define SERVER_PORT 17000 
#define MESSAGE_SIZE 256 
WSADATA Winsock; 
SOCKET Socket; 
sockaddr_in ServerAddress; 
char Buffer[MESSAGE_SIZE]; 
int main() 
{ 
    WSAStartup(MAKEWORD(2,2),&Winsock); 
    if(LOBYTE(Winsock.wVersion) != 2 || HIBYTE(Winsock.wVersion) != 2) 
    { 
     WSACleanup(); 
     return 1; 
    } 

    Socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 
    ZeroMemory(&ServerAddress, sizeof(ServerAddress)); 
    ServerAddress.sin_family = AF_INET; 
    ServerAddress.sin_addr.s_addr = inet_addr(SERVER_ADDRESS); 
    ServerAddress.sin_port = SERVER_PORT; 

    while(true) 
    { 
     gets(Buffer); 
     sendto(Socket, Buffer, MESSAGE_SIZE, 0, (sockaddr*)&ServerAddress, sizeof(ServerAddress)); 
     if(Buffer[0]== ' ') 
     { 
      break; 
     } 
    } 
    WSACleanup(); 
    return 0; 
} 

和服務器的代碼:

#define _WINSOCK_ 
#include <WinSock2.h> 
#include <stdio.h> 
#pragma comment(lib, "ws2_32.lib") 
#define SERVER_ADDRESS "127.0.0.1" 
#define SERVER_PORT 17000 
#define MESSAGE_SIZE 256 
WSADATA Winsock; 
SOCKET Socket; 
char Buffer[MESSAGE_SIZE]; 
sockaddr_in ServerAddress; 
int SizeInt = sizeof(ServerAddress); 
int main() 
{ 
    WSAStartup(MAKEWORD(2,2), &Winsock); 
    if(LOBYTE(Winsock.wVersion) != 2 || HIBYTE(Winsock.wVersion) != 2) 
    { 
     WSACleanup(); 
     return 1; 
    } 
    Socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 
    ZeroMemory(&ServerAddress, sizeof(ServerAddress)); 
    //ServerAddress.sin_addr.s_addr = inet_addr(SERVER_ADDRESS); 
    ServerAddress.sin_family = AF_INET; 
    ServerAddress.sin_port = SERVER_PORT; 
    bind(Socket, (sockaddr*)&ServerAddress, sizeof(ServerAddress)); 
    while(true) 
    { 
     if(recvfrom(Socket, Buffer, MESSAGE_SIZE, 0, (sockaddr*)&ServerAddress, &SizeInt)) 
     { 
      Buffer[MESSAGE_SIZE - 1] = '\0'; 
      printf("RECEIVED: "); 
      printf(Buffer); 
      printf("\n"); 

      if(Buffer[0] == ' ') 
      { 
       break; 
      } 
     } 
    } 
    WSACleanup(); 
    return 0; 
} 
+0

您是從「內部」測試您的公共IP嗎?無論如何,大多數路由器都不會讓你這樣做。確保您正在使用網絡外部的客戶端進行測試。 – Joe

+0

你是什麼意思,它不會工作?你如何進行失敗的測試? NATted子網內的客戶端和服務器,還是其中之一?哪一個?服務器綁定全局還是本地地址?客戶端是否嘗試連接到全局或本地地址? –

+0

如果此代碼適用於本地IP,則問題可能不在代碼中。 ipconfig的結果和你看到的http://www.whatismyip.com的結果是什麼? –

回答

2

除非你的計算機的網絡接口直接分配您的IP面向Internet的,你應該總是綁定到LAN IP。綁定的IP地址只是定義了程序將用於通信的網絡接口。

WinSock bind() documentation,你似乎可以綁定到INADDR_ANY偵聽所有接口。

可能的配置:在同一臺計算機上

  1. 客戶端。將服務器綁定到localhost(127.0.0.1),並使用客戶端連接到localhost。

  2. 客戶端在同一網絡上。將服務器綁定到您的LAN IP(類似於192.168.1.10),並使用客戶端連接到LAN IP。

  3. 客戶端通過互聯網。將服務器綁定到LAN IP,從路由器轉發端口,然後使用客戶端連接到WAN/Internet IP。

  4. 客戶都在互聯網和局域網。將服務器綁定到您的LAN IP並從您的路由器轉發端口。您可以連接到局域網的局域網IP和互聯網客戶端的廣域網/互聯網IP。

對於選項4,某些網絡將允許您從LAN內部連接到WAN IP,從而簡化配置。在簡單的家庭路由器上,可以通過路由器設置中的「NAT Loopback」等選項啓用該功能。它經常靠近諸如「允許ping/Internet上的ICMP」,「SPI防火牆」和「塊識別端口」等設置。