aloshuwa 发表于 2013-06-07 12:01

双socket分别bind两个公网IP地址,只有一个能做TCP连接,另一个失败。

想搭个Xstunt server做P2P穿透, 需要一个服务器有两个公网IP(A和B),发现建立连接的时候还是失败。后来发现第2个IP地址(B)的TCP 3次握手不成功。大概看了它的源码,程序是创建两个socket分别bind在这两个公网IP上。

后来我自己写了个简单的程序,创建两个TCP socket,分别bind这两个公网IP地址。结果从远程连这个服务器,发现还真的只有其中一个IP能连得上,另一个会超时。我已经在服务器上用netstat -ntlp命令来查看,的确是两个IP在监听。

注:我的测试客户端是用命令“nc <IP> <PORT>"来做测试的。

另外:如果是直接在服务器上来连这两个socket是都可以成功的,就是从远程来连就不行。谁能指导下?

把服务器程序放在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 /*服务器监听端口号 */
#define BACKLOG 10 /* 最大同时连接请求数 */

int main(int argc, char **argv)
{
int sockfd,client_fd; /*sock_fd:监听socket;client_fd:数据传输socket */
struct sockaddr_in my_addr; /* 本机地址信息 */
struct sockaddr_in remote_addr; /* 客户端地址信息 */
int sin_size;
int maxfd;
fd_set rfds;
int i;

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

// 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);
bzero(&(my_addr.sin_zero),8);

if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) {
    perror("bind出错!");
    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);
bzero(&(my_addr.sin_zero),8);
if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) {
    perror("bind出错!");
    exit(1);
}

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

if(sockfd > sockfd)
   maxfd = sockfd;
else
    maxfd = sockfd;

while(1) {

    FD_ZERO(&rfds);
    FD_SET(sockfd, &rfds);
    FD_SET(sockfd, &rfds);

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

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

      if ((client_fd = accept(sockfd, (struct sockaddr *)&remote_addr, (socklen_t *)&sin_size)) == -1) {
      perror("accept出错");
      continue;
      }
    }
    else if(FD_ISSET(sockfd, &rfds))
    {
      printf("sockfd(%s) is readable\n", argv);
      if ((client_fd = accept(sockfd, (struct sockaddr *)&remote_addr, (socklen_t *)&sin_size)) == -1) {
      perror("accept出错");
      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()) { /* 子进程代码段 */
      if (send(client_fd, "Hello, you are connected!\n", 26, 0) == -1)
          perror("send出错!");
      //sleep(10);
      close(client_fd);
      exit(0);
    }   
    close(client_fd);
   }
}

huangya90 发表于 2013-06-09 23:40

经测试,是没有问题的。你的服务器的B ip地址配置有可能错误。
页: [1]
查看完整版本: 双socket分别bind两个公网IP地址,只有一个能做TCP连接,另一个失败。