2

我尝试在 Linux(http://www.cis.nctu.edu.tw/~gis87577/xDreaming/XSTUNT/index.html)上设置 XSTUNT 服务器来进行 p2p 遍历,但失败了。我阅读了它的源代码。我发现应用程序创建了两个 TCP 套接字,然后将它们分别绑定到两个公共 IP 地址。远程客户端只能连接一个公共 IP 地址。

所以我写了一个简单的服务器应用程序来测试这个环境。在远程客户端上,我使用这两个命令“nc [public IP_A] [PORT]”和“nc [public IP_B] [PORT]”来尝试连接到服务器。只有一个成功,另一个失败。我已经嗅探了客户端的流量,失败的nc无法从服务器获取“SYN-ACK”包。是路线问题吗?我的两个公共接口没有特殊网关。因为我使用PPPoE连接互联网。所以我只得到 ppp0 和 ppp1。如果路由表导致此问题,我不知道如何更改路由表。

但是,如果我在运行我的服务器应用程序的服务器上执行这两个命令,则两个命令都成功。谁能告诉我为什么?

注意:我在 Windows 上使用 cygwin 编译了这个服务器应用程序。结果是一样的。

这是我的服务器应用程序的代码

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

#define SERVPORT 3333 /* Listen Port */
#define BACKLOG 10 

int main(int argc, char **argv)
{
  int sockfd[2],client_fd; 
  struct sockaddr_in my_addr; 
  struct sockaddr_in remote_addr; /* client socket info */
  int sin_size;
  int maxfd;
  fd_set rfds;
  int i;

  if(argc != 3)
    {
      printf("Usage: %s <IP_1> <IP_2>\n", argv[0]);
      return 1;
    }
  for(i = 0; i < 2; i++)
  {
    if ((sockfd[i] = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
      perror("socket error!"); exit(1);
    }
    else
    {
      printf("Create sockfd[%d] = %d\n", i, sockfd[i]);
   }
  }

  // set the first Socket
  my_addr.sin_family=AF_INET;
  my_addr.sin_port=htons(SERVPORT);
  my_addr.sin_addr.s_addr = inet_addr(argv[1]);
  bzero(&(my_addr.sin_zero),8);

  if (bind(sockfd[0], (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) {
    perror("bind error!");
    exit(1);
  }

  // set the second Socket
  my_addr.sin_family=AF_INET;
  my_addr.sin_port=htons(SERVPORT);
  my_addr.sin_addr.s_addr = inet_addr(argv[2]);
  bzero(&(my_addr.sin_zero),8);
  if (bind(sockfd[1], (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) {
    perror("bind error!");
    exit(1);
  }

  for(i = 0; i < 2; i++)
  {
    if (listen(sockfd[i], BACKLOG) == -1) {
      perror("listen error!");
      exit(1);
    }
  }

  if(sockfd[0] > sockfd[1])
    maxfd = sockfd[0];
  else
    maxfd = sockfd[1];

  while(1) {

    FD_ZERO(&rfds);
    FD_SET(sockfd[0], &rfds);
    FD_SET(sockfd[1], &rfds);

    printf("waiting client\n");
    select(maxfd + 1, &rfds, NULL, NULL, NULL);

    sin_size = sizeof(struct sockaddr_in);
    if(FD_ISSET(sockfd[0], &rfds))
    {
      printf("sockfd[0](%s) is readable\n", argv[1]);

      if ((client_fd = accept(sockfd[0], (struct sockaddr *)&remote_addr, (socklen_t *)&sin_size)) == -1) {
        perror("accept error");
        continue;
      }
    }
    else if(FD_ISSET(sockfd[1], &rfds))
    {
      printf("sockfd[1](%s) is readable\n", argv[2]);
      if ((client_fd = accept(sockfd[1], (struct sockaddr *)&remote_addr, (socklen_t *)&sin_size)) == -1) {
        perror("accept error");
        continue;
      }
    }
    else
    {
      printf("select error\n");
      continue;
    }

    printf("received a connection from %s:%d\n\n", (char *)inet_ntoa(remote_addr.sin_addr), ntohs(remote_addr.sin_port));
    if (!fork()) { /* child process */
      if (send(client_fd, "Hello, you are connected!\n", 26, 0) == -1)
        perror("send error!");
      close(client_fd);
      exit(0);
    }
    close(client_fd);
  }
}
4

0 回答 0