Sockets 无法连接与服务器中的两个公用IP地址绑定的两个套接字

Sockets 无法连接与服务器中的两个公用IP地址绑定的两个套接字,sockets,tcp,Sockets,Tcp,我试图在Linux()上设置一个XSTUNT服务器来进行p2p遍历,但失败了。我读了它的源代码。我发现应用程序创建了两个TCP套接字,然后将它们分别绑定到两个公共IP地址。远程客户端只能连接一个公共IP地址 所以我编写了一个简单的服务器应用程序来测试这个环境。 在远程客户端上,我使用这两个命令 “nc[公共IP_A][端口]”和 “nc[公共IP_B][端口]” 尝试连接到服务器。只有一个成功,而另一个失败。我已经嗅探了客户端上的流量,失败的nc无法从服务器获取“SYN-ACK”包。是路线问题吗

我试图在Linux()上设置一个XSTUNT服务器来进行p2p遍历,但失败了。我读了它的源代码。我发现应用程序创建了两个TCP套接字,然后将它们分别绑定到两个公共IP地址。远程客户端只能连接一个公共IP地址

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

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

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

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

#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);
  }
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#定义SERVPORT 3333/*侦听端口*/
#定义待办事项10
int main(int argc,字符**argv)
{
int sockfd[2],客户机\u fd;
我的地址中的结构sockaddr\u;
远程地址中的struct sockaddr\u;/*客户端套接字信息*/
国际标准尺寸;
int-maxfd;
fd_集rfds;
int i;
如果(argc!=3)
{
printf(“用法:%s\n”,argv[0]);
返回1;
}
对于(i=0;i<2;i++)
{
if((sockfd[i]=socket(AF\u INET,SOCK\u STREAM,0))=-1){
perror(“套接字错误!”);退出(1);
}
其他的
{
printf(“创建sockfd[%d]=%d\n”,i,sockfd[i]);
}
}
//设置第一个插座
我的地址sin_family=AF_INET;
my_addr.sin_port=htons(SERVPORT);
my_addr.sin_addr.s_addr=inet_addr(argv[1]);
bzero(&(我的地址sin_zero),8);
if(bind(sockfd[0],(struct sockaddr*)和my_addr,sizeof(struct sockaddr))=-1){
perror(“绑定错误!”);
出口(1);
}
//设置第二个插座
我的地址sin_family=AF_INET;
my_addr.sin_port=htons(SERVPORT);
my_addr.sin_addr.s_addr=inet_addr(argv[2]);
bzero(&(我的地址sin_zero),8);
if(bind(sockfd[1],(struct sockaddr*)和my_addr,sizeof(struct sockaddr))=-1){
perror(“绑定错误!”);
出口(1);
}
对于(i=0;i<2;i++)
{
if(侦听(sockfd[i],BACKLOG)=-1){
perror(“侦听错误!”);
出口(1);
}
}
if(sockfd[0]>sockfd[1])
maxfd=sockfd[0];
其他的
maxfd=sockfd[1];
而(1){
FD_ZERO(和RFD);
FD_集(sockfd[0],&rfds);
FD_集(sockfd[1],&RFD);
printf(“等待客户端”);
选择(maxfd+1,&rfds,NULL,NULL,NULL);
sin_size=sizeof(结构sockaddr_in);
if(FD_ISSET(sockfd[0],&RFD))
{
printf(“sockfd[0](%s)可读,\n”,argv[1]);
如果((客户端\u fd=accept(sockfd[0],(结构sockaddr*)和远程\u addr,(socklen\u t*)和sin\u size))==-1){
perror(“接受错误”);
继续;
}
}
else if(FD_ISSET(sockfd[1],&RFD))
{
printf(“sockfd[1](%s)可读”,argv[2]);
if((客户端\u fd=accept(sockfd[1],(结构sockaddr*)和远程\u addr,(socklen\u t*)和sin\u size))==-1){
perror(“接受错误”);
继续;
}
}
其他的
{
printf(“选择错误\n”);
继续;
}
printf(“从%s接收到连接:%d\n\n”,(char*)inet\u ntoa(远程地址sin\u addr),ntohs(远程地址sin\u端口));
如果(!fork()){/*子进程*/
如果(发送(客户端?“您好,您已连接!\n”,26,0)=-1)
perror(“发送错误!”);
关闭(客户_fd);
出口(0);
}
关闭(客户_fd);
}
}