为位于不同网络中的节点定义UDP套接字

时间:2013-06-11 19:21:23

标签: c linux sockets network-programming 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

下面是C中的通用UDP(客户端)套接字代码(不包括错误检查以节省问题的空间)。假设以下内容可以在node1上运行。我的问题是如何我需要在下面的代码中定义node2,然后我需要编辑还有什么以便来自{{1}的UDP数据包会没有任何问题吗?

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; } 上)是通用代码,不需要任何特定的修改就可以从node2接收数据包,是吗?

2 个答案:

答案 0 :(得分:3)

路由UDP数据包(以及TCP)不是您应该在代码中解决的任务,它由路由器执行。您应该编写代码,就好像客户端和服务器都在同一个网络上(您当前的代码看起来没问题),但是您还应该设置路由器以便它们:1)允许通过NAT路由UDP,以及2)路由器Node2(5.6.7.8)必须将端口1234的UDP流量转发到Node2的私有地址。

答案 1 :(得分: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);
   }
}