织梦CMS - 轻松建站从此开始!

罗索

最精简完美的P2P测试程序

落鹤生 发布于 2012-02-16 15:36 点击:次 
最精简完美的P2P测试程序(源码)
TAG:

     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 <stdio.h>
    11  #include <stdint.h>
    12  #include <stdlib.h>
    13  #include <string.h>
    14  #include <time.h>
    15  #include <ctype.h>
    16  #include <stdlib.h>
    17  #include <assert.h>
    18  #include <sys/stat.h>
    19
    20  #ifdef WIN32
    21
    22  #include <windows.h>
    23  #include <windef.h>
    24  #include <winsock2.h>
    25  #include <ws2tcpip.h>
    26  #include <iphlpapi.h>
    27  #include <stdio.h>
    28  #include <winioctl.h>
    29
    30  #else
    31
    32  #include <unistd.h>
    33  #include <sys/types.h>
    34  #include <sys/socket.h>
    35  #include <netdb.h>
    36  #include <netinet/in.h>
    37  #include <arpa/inet.h>
    38  #include <fcntl.h>
    39  #include <errno.h>
    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  }
 
(kf701)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201202/15727.html]
本文出处:blog.chinaunix.net 作者:kf701 原文
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容