客户端示例:

  1. #include "Net.h"
  2. #include "../p2pInfo.h"
  3. int main()
  4. {
  5. CUdp  udp;
  6. if (0!=udp.Open(16888))
  7. {
  8. printf("client udp open failed \n");
  9. return -1;
  10. }
  11. P2P_CLIENT_INFO clientInfo;
  12. memset(&clientInfo,0,sizeof(P2P_CLIENT_INFO));
  13. clientInfo.nClientPort=16888;
  14. clientInfo.nID=0;
  15. sprintf(clientInfo.sClientIP,"%s","10.10.2.161");
  16. P2P_CMD_HEAD cmdHead;
  17. cmdHead.nCmd=P2P_CMD_REGISTER_REQ;
  18. cmdHead.nPayloadLen=sizeof(P2P_CLIENT_INFO);
  19. memcpy(cmdHead.sPayLoad,&clientInfo,sizeof(P2P_CLIENT_INFO));
  20. long lDestIP=0;
  21. CBSocket::ConvertStringToIP((int*)&lDestIP,"114.247.165.37");
  22. int nRet=0;
  23. nRet=udp.Send((unsigned char *)&cmdHead,CMD_HEAD_LEN+cmdHead.nPayloadLen,lDestIP,P2P_SERVER_PORT);
  24. printf("send register len %d \n",nRet);
  25. nRet=udp.Recv();
  26. if (nRet>0)
  27. {
  28. printf("recv data \n");
  29. }
  30. else
  31. {
  32. printf("recv P2P_CMD_REGISTER_ACK time out \n");
  33. return 0;
  34. }
  35. P2P_CLIENT_INFO remoteClientInfo;
  36. memset(&remoteClientInfo,0,sizeof(P2P_CLIENT_INFO));
  37. P2P_CMD_HEAD recvHead;
  38. memset(&recvHead,0,sizeof(P2P_CMD_HEAD));
  39. while (1)
  40. {
  41. cmdHead.nCmd=P2P_CMD_COMUNICATION_REQ;
  42. cmdHead.nValue=1;    // remote id
  43. cmdHead.nPayloadLen=sizeof(P2P_CLIENT_INFO);
  44. nRet=udp.Send((unsigned char *)&cmdHead,CMD_HEAD_LEN+cmdHead.nPayloadLen,lDestIP,P2P_SERVER_PORT);
  45. printf("send commuication len %d \n",nRet);
  46. nRet=udp.Recv();
  47. if (nRet>0)
  48. {
  49. memcpy(&recvHead,udp.GetBuffer(),nRet);
  50. if (0==recvHead.nValue)
  51. {
  52. memcpy(&remoteClientInfo,recvHead.sPayLoad,sizeof(P2P_CLIENT_INFO));
  53. printf("recv P2P_CMD_COMUNICATION_ACK remote ip:%s port:%d\n",
  54. remoteClientInfo.sClientPublicIP,remoteClientInfo.nClientPublicPort);
  55. break;
  56. }
  57. usleep(100*1000);
  58. }
  59. else
  60. {
  61. printf("recv P2P_CMD_COMUNICATION_ACK time out \n");
  62. }
  63. }
  64. // send udp hole to remote ip
  65. CBSocket::ConvertStringToIP((int*)&lDestIP,remoteClientInfo.sClientPublicIP);
  66. cmdHead.nCmd=P2P_CMD_UDP_HOLE_REQ;
  67. cmdHead.nPayloadLen=0;
  68. udp.Send((unsigned char *)&cmdHead,CMD_HEAD_LEN,lDestIP,remoteClientInfo.nClientPublicPort);
  69. usleep(1000*1000);
  70. udp.Send((unsigned char *)&cmdHead,CMD_HEAD_LEN,lDestIP,remoteClientInfo.nClientPublicPort);
  71. usleep(1000*1000);
  72. udp.Send((unsigned char *)&cmdHead,CMD_HEAD_LEN,lDestIP,remoteClientInfo.nClientPublicPort);
  73. nRet=udp.Recv();
  74. if (nRet>0)
  75. {
  76. memcpy(&recvHead,udp.GetBuffer(),nRet);
  77. if (recvHead.nCmd==P2P_CMD_UDP_HOLE_ACK || recvHead.nCmd==P2P_CMD_UDP_HOLE_REQ)
  78. {
  79. printf("recv P2P_CMD_UDP_HOLE  udp hole success\n");
  80. }
  81. }
  82. else
  83. {
  84. printf("P2P_CMD_UDP_HOLE recv out \n");
  85. return 0;
  86. }
  87. return 0;
  88. }

服务器端示例:

  1. #include "Net.h"
  2. #include "../p2pInfo.h"
  3. #define MAX_CLIENT_COUNT 16
  4. P2P_CLIENT_INFO* pClientList[MAX_CLIENT_COUNT];
  5. void AddClient(P2P_CLIENT_INFO* pClientInfo)
  6. {
  7. for(int i=0;i<MAX_CLIENT_COUNT;i++)
  8. {
  9. if (!pClientList[i])
  10. {
  11. P2P_CLIENT_INFO* pClient=new P2P_CLIENT_INFO;
  12. memcpy(pClient,pClientInfo,sizeof(P2P_CLIENT_INFO));
  13. pClientList[i]=pClient;
  14. return;
  15. }
  16. }
  17. }
  18. P2P_CLIENT_INFO* FindClient(int nID)
  19. {
  20. for(int i=0;i<MAX_CLIENT_COUNT;i++)
  21. {
  22. if (pClientList[i])
  23. {
  24. if (nID==pClientList[i]->nID)
  25. {
  26. return pClientList[i];
  27. }
  28. }
  29. }
  30. return NULL;
  31. }
  32. P2P_CLIENT_INFO* FindClient(long ip, unsigned short nPort)
  33. {
  34. for(int i=0;i<MAX_CLIENT_COUNT;i++)
  35. {
  36. if (pClientList[i])
  37. {
  38. int nIp=0;
  39. CBSocket::ConvertStringToIP(&nIp,pClientList[i]->sClientPublicIP);
  40. if (nPort==pClientList[i]->nClientPublicPort && ip==nIp)
  41. {
  42. return pClientList[i];
  43. }
  44. }
  45. }
  46. return NULL;
  47. }
  48. int main()
  49. {
  50. CUdp udp;
  51. udp.Open(P2P_SERVER_PORT);
  52. int nRet=0;
  53. P2P_CMD_HEAD* pCmdHead=new P2P_CMD_HEAD;
  54. P2P_CMD_HEAD* pSendCmdHead=new P2P_CMD_HEAD;
  55. memset(pCmdHead,0,sizeof(P2P_CMD_HEAD));
  56. memset(pSendCmdHead,0,sizeof(P2P_CMD_HEAD));
  57. long lRemoteIP=0;
  58. unsigned short nRemotePort=0;
  59. int i=0;
  60. for (i = 0; i <16; i++)
  61. {
  62. pClientList[i]=NULL;
  63. }
  64. while (1)
  65. {
  66. nRet=udp.Recv(lRemoteIP,nRemotePort);
  67. if (nRet>0)
  68. {
  69. memcpy(pCmdHead,udp.GetBuffer(),nRet);
  70. switch (pCmdHead->nCmd)
  71. {
  72. case P2P_CMD_REGISTER_REQ:
  73. {
  74. printf("recv register req \n");
  75. P2P_CLIENT_INFO* pClient=(P2P_CLIENT_INFO*)pCmdHead->sPayLoad;
  76. CBSocket::ConvertIPToString(lRemoteIP,pClient->sClientPublicIP);
  77. pClient->nClientPublicPort=nRemotePort;
  78. AddClient(pClient);
  79. printf("recv command P2P_CMD_REGISTER_REQ from ip:%s port:%d\n",pClient->sClientPublicIP,pClient->nClientPublicPort);
  80. pSendCmdHead->nCmd=P2P_CMD_REGISTER_ACK;
  81. pSendCmdHead->nPayloadLen=sizeof(P2P_CLIENT_INFO);
  82. memcpy(pSendCmdHead->sPayLoad,pClient,sizeof(P2P_CLIENT_INFO));
  83. udp.Send((unsigned char *)pSendCmdHead,CMD_HEAD_LEN+pSendCmdHead->nPayloadLen,lRemoteIP,nRemotePort);
  84. }
  85. break;
  86. case P2P_CMD_COMUNICATION_REQ:
  87. {
  88. printf("recv command P2P_CMD_COMUNICATION_REQ\n");
  89. P2P_CLIENT_INFO* pTargetClientInfo=FindClient(pCmdHead->nValue);
  90. if (!pTargetClientInfo)
  91. {
  92. printf("not find client info id:%d\n",pCmdHead->nValue);
  93. continue;
  94. }
  95. pSendCmdHead->nCmd=P2P_CMD_COMUNICATION_ACK;
  96. pSendCmdHead->nPayloadLen=sizeof(P2P_CLIENT_INFO);
  97. memcpy(pSendCmdHead->sPayLoad,pTargetClientInfo,sizeof(P2P_CLIENT_INFO));
  98. udp.Send((unsigned char *)pSendCmdHead,CMD_HEAD_LEN+pSendCmdHead->nPayloadLen,lRemoteIP,nRemotePort);
  99. // send to remote client
  100. int nIP=0;
  101. P2P_CLIENT_INFO* pSelfClientInfo=FindClient(lRemoteIP,nRemotePort);
  102. if (pSelfClientInfo)
  103. {
  104. printf("find self client info ip:%s\n",pSelfClientInfo->sClientPublicIP);
  105. memcpy(pSendCmdHead->sPayLoad,pSelfClientInfo,sizeof(P2P_CLIENT_INFO));
  106. CBSocket::ConvertStringToIP(&nIP,pTargetClientInfo->sClientPublicIP);
  107. udp.Send((unsigned char *)pSendCmdHead,CMD_HEAD_LEN+pSendCmdHead->nPayloadLen,nIP,pTargetClientInfo->nClientPublicPort);
  108. }
  109. else
  110. {
  111. printf("not find self client info");
  112. }
  113. }
  114. break;
  115. default:
  116. break;
  117. }
  118. }
  119. else
  120. {
  121. printf("udp recv time out \n");
  122. }
  123. }
  124. return 0;
  125. }

示例下载地址:    http://download.csdn.net/detail/mtour/8119489

UDP 打洞示例 包含 服务器 客户端的更多相关文章

  1. c++下基于windows socket的服务器客户端程序(基于UDP协议)

    前天写了一个基于tcp协议的服务器客户端程序,今天写了一个基于UDP协议的,由于在上一篇使用TCP协议的服务器中注释已经较为详细,且许多api的调用是相同的,故不再另外注释. 使用UDP协议需要注意几 ...

  2. UDP打洞、P2P组网方式研究

    catalogue . NAT概念 . P2P概念 . UDP打洞 . P2P DEMO . ZeroNet P2P 1. NAT概念 在STUN协议中,根据内部终端的地址(LocalIP:Local ...

  3. UDP 打洞 原理解释

    终于找到了一份满意的UDP打洞原理解释,附上正文,自己整理了一下源码 3.3. UDP hole punching UDP打洞技术 The third technique, and the one o ...

  4. udp打洞( NAT traversal )的方法介绍

    http://www.cnblogs.com/whyandinside/archive/2010/12/08/1900492.html http://www.gzsec.com/oldversion/ ...

  5. UDP打洞原理及代码

    来源:http://www.fenbi360.net/Content.aspx?id=1021&t=jc UDP"打洞"原理 1.       NAT分类 根据Stun协议 ...

  6. Python实现简单的udp打洞(P2P)

    UDP穿越NAT的具体设计 首先,Client A登录服务器,NAT 1为这次的Session分配了一个端口60000,那么Server S收到的Client A的地址是200.0.0.132:600 ...

  7. C# p2p UDP穿越NAT,UDP打洞源码

    思路如下(参照源代码): 1. frmServer启动两个网络侦听,主连接侦听,协助打洞的侦听. 2. frmClientA和frmClientB分别与frmServer的主连接保持联系. 3. 当f ...

  8. QUdpSocket-Qt使用Udp通讯实现服务端和客户端

    版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:QUdpSocket-Qt使用Udp通讯实现服务端和客户端     本文地址:https:// ...

  9. Udp打洞原理和源代码。

    所谓udp打洞就是指客户端A通过udp协议向服务器发送数据包,服务器收到后,获取数据包,并且 可获取客户端A地址和端口号.同样在客户端B发送给服务器udp数据包后,服务器同样在收到B发送过来 的数据包 ...

随机推荐

  1. 记录遇到的ios下的bugs[废弃]

    请看又一次排版后的文章 新地址

  2. Ural 1303 Minimal Coverage(贪心)

    题目地址:Ural 1303 先按每一个线段的左端点排序,然后设置一个起点s.每次都从起点小于等于s的线段中找到一个右端点最大的. 并将该右端点作为新的起点s,然后继续找. 从左到右扫描一遍就可以. ...

  3. Canny边缘检测及C++实现

    Canny边缘检测算法是澳大利亚科学家John F. Canny在1986年提出来的,不得不提一下的是当年John Canny本人才28岁!到今天已经30年过去了,Canny算法仍然是图像边缘检测算法 ...

  4. 26.angularJS $routeProvider

    转自:https://www.cnblogs.com/best/tag/Angular/ O'Reilly书上的伪代码 var someModule = angular.module('someMod ...

  5. Spring Security 4 Method security using @PreAuthorize,@PostAuthorize, @Secured, EL--转

    原文地址:http://websystique.com/spring-security/spring-security-4-method-security-using-preauthorize-pos ...

  6. Linux桌面词典 GoldenDict词典

    GoldenDict 是一款不错的.与StarDict(星际译王)类似的词典软件.它使用 WebKit作为渲染核心,格式化.颜色.图像.链接等支持一应俱全:支持多种词典文件格式,包括Babylon的 ...

  7. pythong中的全局变量的调用和嵌套函数中变量的使用

    全局变量调用:想要在自定义的函数中使用全局变量,就得要在函数用关键字global声明,然后就可以对全局变量进行修改.嵌套函数中的变量的调用:要在嵌套的变量中,使用nonlocal的声明'''num = ...

  8. Supervisor 的安装与配置教程

    简介 Supervisor是一个进程控制系统. 它是一个C/S系统(注意: 其提供WEB接口给用户查询和控制), 它允许用户去监控和控制在类UNIX系统的进程. 它的目标与launchd, daemo ...

  9. 【Codeforces Round #460 (Div. 2) C】 Seat Arrangements

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 用pre[i][j]表示第i行前j列的和. 然后枚举连续座位的最左上点. (有两种可能向右或向下k个. 则还需要处理出pre2[i] ...

  10. Tomcat 的三种高级运行模式

    Tomcat 的连接器有两种:HTTP和AJP AJP(Apache JServ Protocol):AJP是面向数据包的基于TCP/IP的协议,它在Apache和Tomcat的实例之间提供了一个专用 ...