Chinaunix首页 | 论坛 | 博客
  • 博客访问: 666593
  • 博文数量: 36
  • 博客积分: 8068
  • 博客等级: 中将
  • 技术积分: 1377
  • 用 户 组: 普通用户
  • 注册时间: 2005-04-11 22:36
文章存档

2011年(2)

2010年(1)

2009年(20)

2008年(13)

我的朋友

分类: 系统运维

2011-03-04 11:01:56

原文地址:


     1  /*
     2   * P2P Test
     3   * kf701.ye, bob.suju
     4   *
     5   * Compile:
     6   * Linux:   gcc p2p.c -o p2p.out
     7   * Windows: gcc p2p.c -o p2p.out -lws2_32
     8   */
     9
    10  #include
    11  #include
    12  #include
    13  #include
    14  #include
    15  #include
    16  #include
    17  #include
    18  #include
    19
    20  #ifdef WIN32
    21
    22  #include
    23  #include
    24  #include
    25  #include
    26  #include
    27  #include
    28  #include
    29
    30  #else
    31
    32  #include
    33  #include
    34  #include
    35  #include
    36  #include
    37  #include
    38  #include
    39  #include
    40
    41  #define SOCKET int
    42
    43  #endif
    44
    45
    46  #ifdef WIN32
    47  void initWin32() {
    48          WSADATA wsaData;
    49          int err;
    50
    51          err = WSAStartup(MAKEWORD(2, 2), &wsaData );
    52          if( err != 0 ) {
    53                  /* Tell the user that we could not find a usable */
    54                  /* WinSock DLL.                                  */
    55                  printf("FATAL ERROR: unable to initialise Winsock 2.x.");
    56                  exit(-1);
    57          }
    58  }
    59  #endif
    60
    61  SOCKET open_udp_socket(uint16_t local_port)
    62  {
    63          SOCKET sock_fd;
    64          struct sockaddr_in local_address;
    65          int sockopt = 1;
    66
    67          if((sock_fd = socket(AF_INET, SOCK_DGRAM, 0))  < 0) {
    68                  return(-1);
    69          }
    70
    71
    72          setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, (char *)&sockopt, sizeof(sockopt));
    73
    74          memset(&local_address, 0, sizeof(local_address));
    75          local_address.sin_family = AF_INET;
    76          local_address.sin_port = htons(local_port);
    77          local_address.sin_addr.s_addr = INADDR_ANY;
    78          if(bind(sock_fd, (struct sockaddr*) &local_address, sizeof(local_address)) == -1) {
    79                  return(-1);
    80          }
    81
    82          return(sock_fd);
    83  }
    84
    85  char* intoa(uint32_t /* host order */ addr, char* buf, uint16_t buf_len) {
    86    char *cp, *retStr;
    87    uint32_t byte;
    88    int n;
    89
    90    cp = &buf[buf_len];
    91    *--cp = '\0';
    92
    93    n = 4;
    94    do {
    95      byte = addr & 0xff;
    96      *--cp = byte % 10 + '0';
    97      byte /= 10;
    98      if (byte > 0) {
    99        *--cp = byte % 10 + '0';
   100        byte /= 10;
   101        if (byte > 0)
   102          *--cp = byte + '0';
   103      }
   104      *--cp = '.';
   105      addr >>= 8;
   106    } while (--n > 0);
   107
   108    /* Convert the string to lowercase */
   109    retStr = (char*)(cp+1);
   110
   111    return(retStr);
   112  }
   113
   114
   115  void print_addr (struct sockaddr_in *addr)
   116  {
   117          char ip_buf[48];
   118          printf ("%s:%d\n", intoa(ntohl(addr->sin_addr.s_addr), ip_buf, sizeof(ip_buf)), ntohs(addr->sin_port));
   119  }
   120
   121  int Peer (char *serverip)
   122  {
   123          char buf[1024];
   124
   125          SOCKET sock = open_udp_socket (9000);
   126          if (sock < 0)
   127          {
   128                  printf ("open sock faild\n");
   129                  return 0;
   130          }
   131
   132          struct sockaddr_in addr, sa;
   133
   134          addr.sin_family = AF_INET;
   135          addr.sin_port = htons(8888);
   136          addr.sin_addr.s_addr = inet_addr(serverip);
   137
   138          int rc, ret;
   139          socklen_t len = sizeof( struct sockaddr_in );
   140
   141          while (1)
   142          {
   143                  fd_set socket_mask;
   144                  struct timeval wait_time;
   145
   146                  FD_ZERO(&socket_mask);
   147                  FD_SET(sock, &socket_mask);
   148
   149                  wait_time.tv_sec = 1; wait_time.tv_usec = 0;
   150
   151                  rc = select(sock+1, &socket_mask, NULL, NULL, &wait_time);
   152
   153                  if (rc > 0 && FD_ISSET(sock, &socket_mask))
   154                  {
   155                          printf ("--------------------\n");
   156                          memset (buf, 0, sizeof(buf));
   157
   158                          ret = recvfrom (sock, buf, sizeof(buf), 0, (struct sockaddr*)&sa, &len);
   159
   160                          printf ("Recv From: ");
   161                          print_addr (&sa);
   162                          printf ("Recv buf: %s\n", buf);
   163
   164                          if (sa.sin_addr.s_addr == inet_addr(serverip))
   165                          {
   166                                  char *host = strtok(buf, ":");
   167                                  char *port = strtok(NULL, ":");
   168
   169                                  if (host && port)
   170                                  {
   171                                          printf ("Re write addr to: %s:%s\n", host, port);
   172                                          addr.sin_addr.s_addr = inet_addr(host);
   173                                          addr.sin_port = htons(atoi(port));
   174                                  }
   175                          }
   176                          else
   177                          {
   178                                  printf ("Got From peer, P2P OK!\n");
   179                          }
   180                  }
   181                  else
   182                  {
   183                          char *b = "P2PTESTSTRING";
   184                          ret = sendto(sock, b, strlen(b), 0, (struct sockaddr*)&addr, len);
   185                          printf ("send buf len = %d to ",ret);
   186                          print_addr (&addr);
   187                  }
   188          }
   189  }
   190
   191  int Rendezvous()
   192  {
   193          struct sockaddr_in  addr, peers_addr[2];
   194          socklen_t len = sizeof( struct sockaddr_in );
   195          int reach = 0, select_ret, ret;
   196          uint8_t buf[1024];
   197
   198          SOCKET sockfd = open_udp_socket(8888);
   199
   200          while( 1 )
   201          {
   202                  fd_set readset;
   203                  FD_ZERO(&readset);
   204                  FD_SET( sockfd , &readset );
   205
   206                  select_ret = select(sockfd+1, &readset, NULL, NULL, NULL);
   207                  if (select_ret < 0)
   208                  {
   209                          printf("%s,%d: select err,%m\n", __FILE__, __LINE__);
   210                          continue;
   211                  }
   212
   213                  if (FD_ISSET (sockfd, &readset))
   214                  {
   215                          printf ("--------------------\n");
   216                          memset (buf, 0, sizeof(buf));
   217
   218                          ret = recvfrom(sockfd, (void*)buf, sizeof(buf) ,0, (struct sockaddr*)&addr, &len);
   219                          if (ret <= 0)
   220                          {
   221                                  printf("%s: recvfrom err\n", __func__);
   222                                  continue;
   223                          }
   224
   225                          printf ("Recv From: ");
   226                          print_addr (&addr);
   227                          printf ("Recv buf: %s\n", buf);
   228
   229                          if (reach != 0)
   230                          {
   231                                  if (addr.sin_addr.s_addr == peers_addr[0].sin_addr.s_addr)
   232                                  {
   233                                          continue;
   234                                  }
   235                          }
   236
   237
   238                          memcpy(&peers_addr[reach], &addr, len);
   239                          reach++;
   240
   241                          if (reach == 2)
   242                          {
   243                                  char public[64];
   244
   245                                  // -------------------------------------
   246                                  sprintf(public, "%s:%d",
   247                                                  inet_ntoa(peers_addr[0].sin_addr), ntohs(peers_addr[0].sin_port));
   248
   249                                  ret = sendto(sockfd, public, strlen(public),
   250                                                  0, (struct sockaddr*)&peers_addr[1], sizeof(struct sockaddr_in));
   251
   252                                  printf("send to %s:%d msg: %s\n",
   253                                                  inet_ntoa(peers_addr[1].sin_addr), ntohs(peers_addr[1].sin_port), public);
   254
   255
   256                                  // -------------------------------------
   257                                  sprintf(public, "%s:%d",
   258                                                  inet_ntoa(peers_addr[1].sin_addr), ntohs(peers_addr[1].sin_port));
   259
   260                                  ret = sendto(sockfd, public, strlen(public),
   261                                                  0, (struct sockaddr*)&peers_addr[0], sizeof(struct sockaddr_in));
   262
   263                                  printf("send to %s:%d msg: %s\n",
   264                                                  inet_ntoa(peers_addr[0].sin_addr), ntohs(peers_addr[0].sin_port), public);
   265
   266                                  // -------------------------------------
   267                                  printf ("--------- send again -------------\n");
   268                                  // -------------------------------------
   269                                  sprintf(public, "%s:%d",
   270                                                  inet_ntoa(peers_addr[1].sin_addr), ntohs(peers_addr[1].sin_port));
   271
   272                                  ret = sendto(sockfd, public, strlen(public),
   273                                                  0, (struct sockaddr*)&peers_addr[0], sizeof(struct sockaddr_in));
   274
   275                                  printf("send to %s:%d msg: %s\n",
   276                                                  inet_ntoa(peers_addr[0].sin_addr), ntohs(peers_addr[0].sin_port), public);
   277
   278                                  // -------------------------------------
   279                                  sprintf(public, "%s:%d",
   280                                                  inet_ntoa(peers_addr[0].sin_addr), ntohs(peers_addr[0].sin_port));
   281
   282                                  ret = sendto(sockfd, public, strlen(public),
   283                                                  0, (struct sockaddr*)&peers_addr[1], sizeof(struct sockaddr_in));
   284
   285                                  printf("send to %s:%d msg: %s\n",
   286                                                  inet_ntoa(peers_addr[1].sin_addr), ntohs(peers_addr[1].sin_port), public);
   287
   288                                  reach = 0;
   289                          }
   290                  }
   291          }
   292
   293          return 0;
   294  }
   295
   296
   297  int main (int argc, char **argv)
   298  {
   299          if (argc < 2)
   300          {
   301                  printf ("Usage: p2p <0|1> [serverip]\n");
   302                  printf ("  1, run as server\n");
   303                  printf ("  0, run as peer\n");
   304                  printf ("./p2p 1\n");
   305                  printf ("./p2p 0 119.23.34.5\n");
   306                  return 0;
   307          }
   308
   309  #ifdef WIN32
   310          printf ("init windows socket\n");
   311          initWin32();
   312  #endif
   313
   314          if (atoi(argv[1]) == 1)
   315          {
   316                  return Rendezvous ();
   317          }
   318          else
   319          {
   320                  if (argc == 3)
   321                          return Peer (argv[2]);
   322
   323                  printf ("argv error\n");
   324          }
   325
   326          return 0;
   327  }

阅读(3883) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2011-03-04 16:13:09

奇怪了,我也是chinaunix用户,怎么加不了你为好友呢?xphcyh