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

  • 相关阅读:
    专职DBA-MySQL体系结构与基本管理
    JSON
    MIME类型
    文件上传下载
    response常用的方法
    2020.11.27小记
    HTTP请求状态码
    1561. Maximum Number of Coins You Can Get
    1558. Minimum Numbers of Function Calls to Make Target Array
    1557. Minimum Number of Vertices to Reach All Nodes
  • 原文地址:https://www.cnblogs.com/findumars/p/6353158.html
Copyright © 2011-2022 走看看