2013-06-11 61 views
3

節點UDP套接字假設有一些位於兩個不同網絡的兩個Linux機器具有以下配置定義位於不同的網絡

       Node1   Node2 
IPaddr(private)   192.168.0.14  10.25.3.75 
Router modem's IP(real) 1.2.3.4   5.6.7.8 
Netmask (real)   255.255.0.0  255.255.192.0 
Router modem's IP(priv) 192.168.0.1  10.0.20.1 
Netmask (priv)   255.255.255.0 255.0.0.0 

這裏下面是一個通用的UDP(客戶端)套接字代碼在C(不包括錯誤檢查,以節省問題的空間)。假設下面的代碼可以在node1上運行。我的問題是,如何如何在下面的代碼上定義node2還需要編輯哪些以便node1 to node2的UDP數據包可以毫無問題地傳送?

#include <arpa/inet.h> 
#include <netinet/in.h> 
#include <stdio.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <unistd.h> 
#include <stdlib.h> 
#include <string.h> 

#define SRV_IP "5.6.7.8" 

int main(){ 
    struct sockaddr_in serv_addr; 
    int sockfd, i, slen=sizeof(serv_addr); 
    char buf[512] = "hello"; 
    sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 
    bzero(&serv_addr, sizeof(serv_addr)); 
    serv_addr.sin_family = AF_INET; 
    serv_addr.sin_port = htons(1234); 
    inet_aton(SRV_IP, &serv_addr.sin_addr); 
    sendto(sockfd, buf, BUFLEN, 0, (struct sockaddr*)&serv_addr, slen); 
    close(sockfd); 
    return 0; 
} 

我假設UDP服務器部分(上node2)是一個通用的代碼,不需要任何具體的修改從node1接收數據包,是不是?

回答

3

路由UDP數據包(以及TCP)是不是你要解決的任務在你的代碼中,它由路由器執行。你應該寫你的代碼,就好像客戶端和服務器在同一個網絡上一樣(你當前的代碼看起來不錯),但是你還應該設置你的路由器,以便它們:1)允許通過NAT路由UDP,以及2) Node2(5.6.7.8)必須將端口1234的UDP流量轉發到Node2的私有地址。

+0

我很好奇另外一個問題。我沒有注意到UDP 1234是一個已經定義好的端口。你知道我是否可以在套接字上使用任何多用途UDP端口號,這樣我就不需要處理路由器上的端口轉發(因爲我可能無法訪問路由器進行配置)? – Angs

+1

不幸的是,我不知道在所有路由器上打開的常用UDP端口,並且恐怕這些端口不會是多用途的。但無論如何,如果不在NAT服務器的路由器上設置端口轉發,就不能在NAT後面有服務器(即沒有「真正的」IP地址的服務器)。 – Inspired

+0

謝謝你的進一步解釋! – Angs

0

這裏是我大學時的一個代碼,希望這將有助於

/* Sample UDP server */ 

#include <sys/socket.h> 
#include <netinet/in.h> 
#include <stdio.h> 

int main(int argc, char**argv) 
{ 
    int sockfd,n; 
    struct sockaddr_in servaddr,cliaddr; 
    socklen_t len; 
    char mesg[1000]; 

    sockfd=socket(AF_INET,SOCK_DGRAM,0); 

    bzero(&servaddr,sizeof(servaddr)); 
    servaddr.sin_family = AF_INET; 
    servaddr.sin_addr.s_addr=htonl(INADDR_ANY); 
    servaddr.sin_port=htons(32000); 
    bind(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr)); 

    for (;;) 
    { 
     len = sizeof(cliaddr); 
     n = recvfrom(sockfd,mesg,1000,0,(struct sockaddr *)&cliaddr,&len); 
     sendto(sockfd,mesg,n,0,(struct sockaddr *)&cliaddr,sizeof(cliaddr)); 
     printf("-------------------------------------------------------\n"); 
     mesg[n] = 0; 
     printf("Received the following:\n"); 
     printf("%s",mesg); 
     printf("-------------------------------------------------------\n"); 
    } 
} 

和客戶

/* Sample UDP client */ 

#include <sys/socket.h> 
#include <netinet/in.h> 
#include <stdio.h> 

int main(int argc, char**argv) 
{ 
    int sockfd,n; 
    struct sockaddr_in servaddr,cliaddr; 
    char sendline[1000]; 
    char recvline[1000]; 

    if (argc != 2) 
    { 
     printf("usage: udpcli <IP address>\n"); 
     exit(1); 
    } 

    sockfd=socket(AF_INET,SOCK_DGRAM,0); 

    bzero(&servaddr,sizeof(servaddr)); 
    servaddr.sin_family = AF_INET; 
    servaddr.sin_addr.s_addr=inet_addr(argv[1]); 
    servaddr.sin_port=htons(32000); 

    while (fgets(sendline, 10000,stdin) != NULL) 
    { 
     sendto(sockfd,sendline,strlen(sendline),0, 
      (struct sockaddr *)&servaddr,sizeof(servaddr)); 
     n=recvfrom(sockfd,recvline,10000,0,NULL,NULL); 
     recvline[n]=0; 
     fputs(recvline,stdout); 
    } 
}