我對我的實驗有以下配置。從Windows 7無法訪問Linux UDP服務器
- Wifi(貝爾金)路由器連接到互聯網。
- Windows 7操作系統的筆記本電腦
- Ubuntu操作系統的筆記本電腦。
實驗:當我我的兩個筆記本電腦連接到Wi-Fi路由器它分配IP地址的DHCP 192.168.2.2到Linux & 192.168.2.3贏得他們兩個都很可以瀏覽互聯網。 我用下面的代碼在我的Linux機器上啓動一個UDP服務器。
int main(int argc, char *argv[]) {
int sd, rc, n, cliLen, flags;
struct sockaddr_in cliAddr, servAddr;
char msg[MAX_MSG];
//Create a socket
sd=socket(AF_INET, SOCK_DGRAM, 0);
if(sd<0){ printf("%s: cannot open socket \n",argv[0]); exit(1); }
//Bind now to a port
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = inet_addr("192.168.2.2");
servAddr.sin_port = htons(9999);
rc = bind (sd, (struct sockaddr *) &servAddr,sizeof(servAddr));
if(rc<0) {printf("%s: cannot bind port number %d \n", argv[0], 9999);exit(1);}
//We are done ... Notify User
printf("%s: waiting for data on port UDP %u\n",argv[0],LOCAL_SERVER_PORT);
//Server's Infinite Loop
while(1)
{
memset(msg,0x0,MAX_MSG);//Sanity
/* receive message */
cliLen = sizeof(cliAddr);
n = recvfrom(sd, msg, MAX_MSG, flags,(struct sockaddr *) &cliAddr, (socklen_t *)&cliLen);
if(n<0){printf("%s: cannot receive data \n",argv[0]);continue;}
//Received message
printf("%s: from %s:UDP%u : %s \n", argv[0],inet_ntoa(cliAddr.sin_addr),ntohs(cliAddr.sin_port),msg);
sleep(1);
//Sending back the data thus received
sendto(sd,msg,n,flags,(struct sockaddr *)&cliAddr,cliLen);
}//while
return 0;
}
此代碼工作做好&我可以接收數據包到服務器時,Linux機器上的一些本地客戶端嘗試聯繫我的服務器。
問題:當我在Android AVD中製作同一客戶端時,出現在我的Windows 7系統中,無法連接到我的服務器。
我以爲可能是防火牆問題,所以我刪除了防火牆&通過自定義規則添加到IP「192.168.2.2」,如下面的鏈接中給出的。 http://www.brighthub.com/computing/windows-platform/articles/40014.aspx# 但它沒有奏效。我認爲首先我應該嘗試使用原始的java,然後使用AVD。 因此,我用Java代碼創建了一個UDP客戶端,但仍無法連接到服務器。
然後我想我們試着用原始的C++,這樣我纔會明白到底是什麼問題。以下是我爲此所實施的Visual Studio代碼。
#define PORT_NUM 9999 // Port number used
#define IP_ADDR "192.168.2.2" // IP address of server1
#define BUFFER_SIZE 4096
void main(void){
WORD wVersionRequested = MAKEWORD(2,2); // Stuff for WSA functions
WSADATA wsaData; // Stuff for WSA functions
int client_s; // Client socket descriptor
struct sockaddr_in server_addr; // Server Internet address
int addr_len; // Internet address length
char out_buf[BUFFER_SIZE]; // Output buffer for data
char in_buf[BUFFER_SIZE]; // Input buffer for data
int retcode; // Return code
// This stuff initializes winsock
WSAStartup(wVersionRequested, &wsaData);
client_s = socket(AF_INET, SOCK_DGRAM, 0);
if (client_s < 0){ printf("*** ERROR - socket() failed \n"); exit(-1);}
server_addr.sin_family = AF_INET; // Address family to use
server_addr.sin_port = htons(PORT_NUM); // Port num to use
server_addr.sin_addr.s_addr = inet_addr(IP_ADDR); // IP address to use
strcpy(out_buf, "Test message from CLIENT to SERVER");
retcode = sendto(client_s, out_buf, (strlen(out_buf) + 1), 0,(struct sockaddr *)&server_addr, sizeof(server_addr));
if (retcode < 0){printf("*** ERROR - sendto() failed \n");exit(-1);}
addr_len = sizeof(server_addr);
retcode = recvfrom(client_s, in_buf, sizeof(in_buf), 0,(struct sockaddr *)&server_addr, &addr_len);
if (retcode < 0){printf("*** ERROR - recvfrom() failed \n");exit(-1);}
printf("Received from server: %s \n", in_buf);
retcode = closesocket(client_s);
if (retcode < 0){ printf("*** ERROR - closesocket() failed \n");exit(-1);}
WSACleanup();
}
但它給了我目標無法到達的錯誤。
爲了準確找出數據包層面發生了什麼,我在我的ubuntu機器上安裝了「Wireshark」。
我的觀察是......每當我的Windows客戶端執行時,我都會在Wireshark上得到一條類型爲3的消息的ICMP消息3次。對數據包的詳細分析表明該端口無法訪問。
請幫我找出我在這裏失蹤:(。
使用wireshark來調試這些類型的問題。 – 2012-01-09 13:17:24
使用有線連接進行測試。如果WiFi具有較高的數據包丟失率,那麼您的UDP數據包將被悄悄丟棄。 – Indy9000 2012-01-09 13:27:59