zoukankan      html  css  js  c++  java
  • TCP打洞和UDP打洞的区别 (相互直接访问)

    为什么网上讲到的P2P打洞基本上都是基于UDP协议的打洞?难道TCP不可能打洞?还是TCP打洞难于实现? 
        假设现在有内网客户端A和内网客户端B,有公网服务端S。 
        如果A和B想要进行UDP通信,则必须穿透双方的NAT路由。假设为NAT-A和NAT-B。 
         
        A发送数据包到公网S,B发送数据包到公网S,则S分别得到了A和B的公网IP, 
    S也和A B 分别建立了会话,由S发到NAT-A的数据包会被NAT-A直接转发给A, 
    由S发到NAT-B的数据包会被NAT-B直接转发给B,除了S发出的数据包之外的则会被丢弃。 
    所以:现在A B 都能分别和S进行全双工通讯了,但是A B之间还不能直接通讯。 

        解决办法是:A向B的公网IP发送一个数据包,则NAT-A能接收来自NAT-B的数据包 
    并转发给A了(即B现在能访问A了);再由S命令B向A的公网IP发送一个数据包,则 
    NAT-B能接收来自NAT-A的数据包并转发给B了(即A现在能访问B了)。 

        以上就是“打洞”的原理。 

        但是TCP和UDP在打洞上却有点不同。这是因为伯克利socket(标准socket规范)的 
    API造成的。 
        UDP的socket允许多个socket绑定到同一个本地端口,而TCP的socket则不允许。 
        这是这样一个意思:A B要连接到S,肯定首先A B双方都会在本地创建一个socket, 
    去连接S上的socket。创建一个socket必然会绑定一个本地端口(就算应用程序里面没写 
    端口,实际上也是绑定了的,至少java确实如此),假设为8888,这样A和B才分别建立了到 
    S的通信信道。接下来就需要打洞了,打洞则需要A和B分别发送数据包到对方的公网IP。但是 
    问题就在这里:因为NAT设备是根据端口号来确定session,如果是UDP的socket,A B可以 
    分别再创建socket,然后将socket绑定到8888,这样打洞就成功了。但是如果是TCP的 
    socket,则不能再创建socket并绑定到8888了,这样打洞就无法成功。

    http://www.cnblogs.com/key-ok/p/4367386.html

  • 相关阅读:
    Map与实体之间转换
    letsencrypt 免费SSL证书申请, 自动更新
    spring接收json格式的多个对象参数(变通法)
    controller函数中参数列表使用多个@RequestBody
    经典网页设计:30个新鲜出炉的扁平化网站设计《上篇》
    使用 iosOverlay.js 创建 iOS 风格的提示和通知
    字体大宝库:设计师必备的优秀免费英文字体
    RandomUser – 生成随机用户 JSON 数据的 API
    Salvattore:CSS 驱动的 jQuery Masonry 插件
    赞!jsPDF – 基于 HTML5 的强大 PDF 生成工具
  • 原文地址:https://www.cnblogs.com/findumars/p/6353158.html
Copyright © 2011-2022 走看看