Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1145888
  • 博文数量: 341
  • 博客积分: 12744
  • 博客等级: 上将
  • 技术积分: 4040
  • 用 户 组: 普通用户
  • 注册时间: 2008-05-12 09:34
文章分类
文章存档

2014年(1)

2013年(10)

2012年(17)

2011年(63)

2010年(102)

2009年(107)

2008年(41)

分类: LINUX

2012-10-23 10:34:03

网上关于udp打洞都是一些C#的例子,而且写得比较复杂,写了个简单的测试程序,测试通过,但是在客户端在同一个内网此种方法无效,另外udp会丢包,如果一次执行不成功,可以多执行几次。
server.c

点击(此处)折叠或打开

  1. #include <sys/socket.h>
  2. #include <sys/types.h>
  3. #include <errno.h>
  4. #include <string.h>
  5. #include <netinet/in.h>
  6. #include <arpa/inet.h>
  7. #include <stdio.h>

  8. int main(int argc, const char *argv[])
  9. {
  10.     int fd = socket(AF_INET, SOCK_DGRAM, 0);
  11.     if( fd < 0 )
  12.     {
  13.         printf("socket error: %s\n", strerror(errno));
  14.         return 1;
  15.     }

  16.     struct sockaddr_in sa;
  17.     memset(&sa, 0, sizeof(sa));
  18.     sa.sin_family = AF_INET;
  19.     sa.sin_port = htons(10000);
  20.     sa.sin_addr.s_addr = INADDR_ANY;

  21.     int ret = bind(fd, (struct sockaddr *)&sa, sizeof(sa));
  22.     if( ret < 0 )
  23.     {
  24.         printf("bind error: %s\n", strerror(errno));
  25.         return 1;
  26.     }

  27.     struct sockaddr_in ca[2];
  28.     memset(&ca, 0, sizeof(ca));
  29.     char buff[100];
  30.     socklen_t slen;

  31.     int i = 0;
  32.     ssize_t size;
  33.     for(; i < 2; i++)
  34.     {
  35.         size = recvfrom(fd, &buff, sizeof(buff), 0, (struct sockaddr *)&(ca[i]), &slen);
  36.         if( size < 0 )
  37.         {
  38.             printf("recvfrom error: %s\n", strerror(errno));
  39.             return 1;
  40.         }

  41.         printf("recvfrom ip: %s, port: %d\n", inet_ntoa(ca[i].sin_addr), ntohs(ca[i].sin_port));
  42.     }

  43.     size = sendto(fd, &ca[0], sizeof(ca[0]), 0, (struct sockaddr *)&ca[1], sizeof(ca[1]));
  44.     if ( size < 0 )
  45.     {
  46.         printf("sendto error: %s\n", strerror(errno));
  47.         return 1;
  48.     }

  49.     size = sendto(fd, &ca[1], sizeof(ca[1]), 0, (struct sockaddr *)&ca[0], sizeof(ca[0]));
  50.     if ( size < 0 )
  51.     {
  52.         printf("sendto error: %s\n", strerror(errno));
  53.         return 1;
  54.     }

  55.     return 0;
  56. }

client.c

点击(此处)折叠或打开

  1. #include <sys/types.h>
  2. #include <sys/socket.h>
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <errno.h>
  6. #include <netinet/in.h>
  7. #include <arpa/inet.h>

  8. int main(int argc, const char *argv[])
  9. {
  10.     int fd = socket(AF_INET, SOCK_DGRAM, 0);
  11.     if( fd < 0 )
  12.     {
  13.         printf("socket error: %s\n", strerror(errno));
  14.         return 1;
  15.     }

  16.     struct sockaddr_in sa;
  17.     memset(&sa, 0, sizeof(sa));
  18.     sa.sin_family = AF_INET;
  19.     sa.sin_port = htons(10000);
  20.     sa.sin_addr.s_addr = inet_addr("xx.xx.xx.xx");

  21.     char *p = "a";

  22.     ssize_t size = sendto(fd, p, 1, 0, (struct sockaddr *)&sa, sizeof(sa));
  23.     if( size < 0 )
  24.     {
  25.         printf("sendto error: %s\n", strerror(errno));
  26.         return 1;
  27.     }

  28.     printf("send ok recv now\n");

  29.     char buff[100];
  30.     struct sockaddr_in ca;
  31.     socklen_t slen;
  32.     memset(&ca, 0, sizeof(ca));
  33.     size = recvfrom(fd, buff, sizeof(buff), 0, (struct sockaddr *)&ca, &slen);
  34.     if( size < 0 )
  35.     {
  36.         printf("recvfrom error: %s\n", strerror(errno));
  37.         return 1;
  38.     }
  39.     struct sockaddr_in *ps = (struct sockaddr_in *)buff;

  40.     printf("recv another client ip: %s, port: %d\n", inet_ntoa(ps->sin_addr), ntohs(ps->sin_port));

  41.     int i;
  42.     for( i = 0; i < 3; i++ )
  43.     {
  44.         printf("send %d times\n", i);
  45.         p = "hello world";
  46.         ps->sin_family = AF_INET;
  47.         size = sendto(fd, p, strlen(p), 0, (struct sockaddr *)ps, sizeof(struct sockaddr_in));
  48.         if( size < 0 )
  49.         {
  50.             printf("sendto error: %s\n", strerror(errno));
  51.             return 1;
  52.         }

  53.         printf("send %d times ok, recv now\n", i);

  54.         char buf[100] = {0};
  55.         struct sockaddr_in ca1;
  56.         memset(&ca1, 0, sizeof(ca1));
  57.         size = recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr *)&ca1, &slen);
  58.         if( size < 0 )
  59.         {
  60.             printf("recvfrom error: %s\n", strerror(errno));
  61.             return 1;
  62.         }

  63.         printf("recv %d message: %s\n", i, buf);
  64.         sleep(1);
  65.     }

  66.     return 0;
  67. }


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