STUN打洞学习笔记

文章目录

  • STUN打洞学习笔记
    • 学习起因
    • 什么叫打洞?
    • STUN是什么?
    • NAT是什么?
    • NAT类型
      • 完全圆锥型NAT(Full Cone NAT)
      • 地址限制圆锥型NAT(Restricted Cone NAT)
      • 端口限制圆锥型NAT(Port Restricted Cone NAT)
      • 对称型NAT(Symmetric NAT)
    • STUN的功能
    • STUN的NAT类型判断流程
    • STUN服务程序(coturn)
    • 公共STUN服务
    • STUN客户端
    • 抓包分析
      • wirshark配置
      • 抓包结果
      • TEST I
      • TEST II
      • 分析
      • 分析结果
      • 官方说明
    • P2P在什么情况下能通
    • TCP怎么打洞?

学习起因

由于处理GB28181问题时,设计到NAT网络的问题,领导就把6月份的能力提升任务设定为SIP的UDP打洞。
不过我们使用的国标服务器就是公网服务器,每台服务器均有自己的公网IP地址,好像没有打洞的问题,但是工作这么多年,确实有必要针对于NAT网络相关的知识点做一个总结。

什么叫打洞?

摘录自(随便点的链接):http://www.cppblog.com/lapcca/archive/2010/01/28/106663.html

确切地说是穿透NAT,一般使用UDP协议,TCP协议也可以穿透,只是好像没有UDP成功率高。
如果是一般情况,使用STUN协议.
除了要通信的两个端点之外,还有一个有公网IP的一个服务器 STUN server。
一个端点穿过防火墙,发个消息给STUN server,STUN server收到这个包之后 就可以知道该端点通过防火墙映射后的公网地址。
同样道理,STUN sever可以得到另外一个端点的通过它的防火墙映射后的公网地址。
STUN server把得到的这两个地址发给两个端点。
端点得到对方端点的公网地址后,就可以给对方端点发消息。相互就可以通信。
通俗的说,一个端点发一个UDP消息出去之后,就把自己的墙打了一个洞;另外一个端点也把它的墙打了一个洞。然后双方都可以向对方的洞发数据,进行通信 。

UDP打洞和我理解的差不多,作者说的也够直白的了,
笔者也边学边写,这篇帖子的说法是否准确,我也无法辨知。
不过我们就从这篇看起来不太专业的帖子慢慢探讨这个话题。

作者提出一个STUN的概念,STUN是什么概念?

STUN是什么?

摘录自(百度百科):https://baike.baidu.com/item/stun/3131387?fr=aladdin

STUN(Session Traversal Utilities for NAT,NAT会话穿越应用程序)是一种网络协议,它允许位于NAT(或多重NAT)后的客户端找出自己的公网地址,查出自己位于哪种类型的NAT之后以及NAT为某一个本地端口所绑定的Internet端端口。这些信息被用来在两个同时处于NAT路由器之后的主机之间创建UDP通信。该协议由RFC 5389定义。

STUN提供一种服务,可以查询自己的公网地址。
这句话引出了一个比较敏感的概念NAT
相关标准: RFC 5389 Session Traversal Utilities for NAT (STUN)

NAT是什么?

摘录自(百度百科):https://baike.baidu.com/item/nat/320024?fr=aladdin :

NAT(Network Address Translation),是指网络地址转换,1994年提出的。
当在专用网内部的一些主机本来已经分配到了本地IP地址(即仅在本专用网内使用的专用地址),但又想和因特网上的主机通信(并不需要加密)时,可使用NAT方法。
这种方法需要在专用网(私网IP)连接到因特网(公网IP)的路由器上安装NAT软件。装有NAT软件的路由器叫做NAT路由器,它至少有一个有效的外部全球IP地址(公网IP地址)。这样,所有使用本地地址(私网IP地址)的主机在和外界通信时,都要在NAT路由器上将其本地地址转换成全球IP地址,才能和因特网连接。
另外,这种通过使用少量的全球IP地址(公网IP地址)代表较多的私有IP地址的方式,将有助于减缓可用的IP地址空间的枯竭。在RFC 2663中有对NAT的说明。

NAT就是内网映射到公网上,就是进行地址转换

相关标准: RFC 2663 IP Network Address Translator (NAT) Terminology and Considerations

NAT类型

摘录自(这篇帖子不错):https://blog.csdn.net/wgl307293845/article/details/120450626

NAT分类
一般NAT可以分为四种类型

1.Full Cone NAT(完全圆锥型NAT)
内网主机建立一个UDP socket(LocalIP:LocalPort) 第一次使用这个socket给外部主机发送数据时NAT会给其分配一个公网(PublicIP:PublicPort),以后用这个socket向外面任何主机发送数据都将使用这对(PublicIP:PublicPort)。此外,任何外部主机只要知道这个(PublicIP:PublicPort)就可以发送数据给(PublicIP:PublicPort),内网的主机就能收到这个数据包

2.Restricted Cone NAT(地址限制圆锥型NAT)
内网主机建立一个UDP socket(LocalIP:LocalPort) 第一次使用这个socket给外部主机发送数据时NAT会给其分配一个公网(PublicIP:PublicPort),以后用这个socket向外面任何主机发送数据都将使用这对(PublicIP:PublicPort)。此外,如果任何外部主机想要发送数据给这个内网主机,只要知道这个(PublicIP:PublicPort)并且内网主机之前用这个socket曾向这个外部主机IP发送过数据。只要满足这两个条件,这个外部主机就可以用自己的(IP,任何端口)发送数据给(PublicIP:PublicPort),内网的主机就能收到这个数据包

3.Port Restricted Cone NAT(端口限制圆锥型NAT)
内网主机建立一个UDP socket(LocalIP:LocalPort) 第一次使用这个socket给外部主机发送数据时NAT会给其分配一个公网(PublicIP:PublicPort),以后用这个socket向外面任何主机发送数据都将使用这对(PublicIP:PublicPort)。此外,如果任何外部主机想要发送数据给这个内网主机,只要知道这个(PublicIP:PublicPort)并且内网主机之前用这个socket曾向这个外部主机(IP,Port)发送过数据。只要满足这两个条件,这个外部主机就可以用自己的(IP,Port)发送数据给(PublicIP:PublicPort),内网的主机就能收到这个数据包

4.Symmetric NAT(对称型NAT)
内网主机建立一个UDP socket(LocalIP,LocalPort),当用这个socket第一次发数据给外部主机1时,NAT为其映射一个(PublicIP-1,Port-1),以后内网主机发送给外部主机1的所有数据都是用这个(PublicIP-1,Port-1),如果内网主机同时用这个socket给外部主机2发送数据,第一次发送时,NAT会为其分配一个(PublicIP-2,Port-2), 以后内网主机发送给外部主机2的所有数据都是用这个(PublicIP-2,Port-2).如果NAT有多于一个公网IP,则PublicIP-1和PublicIP-2可能不同,如果NAT只有一个公网IP,则Port-1和Port-2肯定不同,也就是说一定不能是PublicIP-1等于 PublicIP-2且Port-1等于Port-2。此外,如果任何外部主机想要发送数据给这个内网主机,那么它首先应该收到内网主机发给他的数据,然后才能往回发送,否则即使他知道内网主机的一个(PublicIP,Port)也不能发送数据给内网主机,这种NAT无法实现UDP-P2P通信。

从上面也描述也可以看出,安全性系数, 对称型 > 端口受限锥型 > 受限锥型 > 全锥型

说的也是这个理儿,但是不配图有点过分,我也尝试解释一下:

完全圆锥型NAT(Full Cone NAT)

内网主机同一个内网IP和端口映射出来的公网IP和端口,任何公网主机向映射的公网IP和端口发送数据包,数据包就可以到达内网主机。

地址限制圆锥型NAT(Restricted Cone NAT)

内网主机同一个内网IP和端口映射出来的公网IP和端口,只要内网主机发过数据包给公网主机,这个公网主机就可以向映射的公网IP和端口发送数据包,数据包就可以到达内网主机。

端口限制圆锥型NAT(Port Restricted Cone NAT)

内网主机同一个内网IP和端口映射出来的公网IP和端口,只要内网主机发过数据包到给公网主机的特定端口,这个公网主机就可以通过特定端口向映射的公网IP和端口发送数据包,数据包就可以到达内网主机。

对称型NAT(Symmetric NAT)

内网主机给不同的公网主机和端口发送数据包,映射出来的公网IP和端口不一样,同时只有内网主机发过数据包到给公网主机的特定端口,这个公网主机才可以通过特定端口特定端口所映射的公网IP和端口发送数据包,数据包才可以到达内网主机。

STUN的功能

摘录自:https://blog.csdn.net/wyl1987527/article/details/80188001

STUN主要有3个功能
(1)获取经过NAT转换后的地址和端口
服务器记录接收到的UDP包的发起地址和端口。
(2)检测是否位于NAT后面
Server 在收到client 发送的UDP包以后,Server 将接收该包的地址和端口利用UDP再传回给client,client把Server发送过来的地址和端口信息与本机的ip地址和端口进行比较,如果不同,说明在NAT后面;如果相同就说明client位于NAT前面,client也是公网。
(3)检测NAT的类型
这个主要发送响应的时候使用不同IP地址和端口或者改变端口等等。这个检测是对NAT一般情况下有效,但是对防火墙就无能为力了,因为防火墙可能不会打开UDP端口。

STUN的NAT类型判断流程

摘录自:https://segmentfault.com/a/1190000008056434

STUN是RFC3489规定的一种NAT穿透方式,它采用辅助的方法探测NAT的IP和端口。STUN的探测过程需要有一个公网IP的STUN server,在NAT后面的UAC必须和此server配合,互相之间发送若干个UDP数据包。UDP包中包含有UAC需要了解的信息,比如NAT外网IP,PORT等等。UAC通过是否得到这个UDP包和包中的数据判断自己的NAT类型。
NAT的探测过程
假设有如下UAC(B),NAT(A),SERVER(C),UAC的IP为IPB,NAT的IP为IPA ,SERVER的IP为IPC1 、IPC2。
STEP1
B向C的IPC1的port1端口发送一个UDP包。C收到这个包后,会把它收到包的源IP和port写到UDP包中,然后把此包通过IPC1和port1发还给B。这个IP和port也就是NAT的外网IP和port,也就是说你在STEP1中就得到了NAT的外网IP。
如果向一个STUN服务器发送数据包后,没有收到STUN的任何回应包,那只有两种可能:1、STUN服务器不存在,或者弄错了port;2、NAT设备拒绝一切UDP包从外部向内部通过(不支持cone NAT)。
当B收到此UDP后,把此UDP中的IP和自己的IP做比较,如果是一样的,就说明自己是在公网,下步NAT将去探测防火墙类型。如果不一样,说明有NAT的存在,系统进行STEP2的操作。
STEP2
B向C的IPC1发送一个UDP包,请求C通过另外一个IPC2和PORT(不同与SETP1的IPC1)向B返回一个UDP数据包(server两个IP是为了检测cone NAT的类型)。
如果B收到了这个数据包,说明NAT来者不拒,不对数据包进行任何过滤,这也就是STUN标准中的full cone NAT。遗憾的是,full cone nat太少了,这也意味着能收到这个数据包的可能性不大。如果没收到,那么系统进行STEP3的操作。
STEP3
B向C的IPC2的port2发送一个数据包,C收到数据包后,把它收到包的源IP和port写到UDP包中,然后通过自己的IPC2和port2把此包发还给B。
和step1一样,B肯定能收到这个回应UDP包。此包中的port是我们最关心的数据。如果这个port和step1中的port一样,那么可以肯定这个NAT是个CONE NAT,否则是对称NAT。道理很简单:根据对称NAT的规则,当目的地址的IP和port有任何一个改变,那么NAT都会重新分配一个port使用,而在step3中,和step1对应,我们改变了IP和port。因此,如果是对称NAT,那这两个port肯定是不同的。
如果到此步的时候PORT是不同的,那么你的STUN已经死了。如果相同,那么只剩下了restrict cone 和port restrict cone,系统用step4探测是是哪一种。
STEP4
B向C的IPC2的一个端口PD发送一个数据请求包,要求C用IPC2和不同于PD的port返回一个数据包给B。
如果B收到了,那也就意味着只要IP相同,即使port不同,NAT也允许UDP包通过,显然这是restrict cone NAT。如果没收到,没别的好说,port restrict NAT。

相关标准: RFC 3489 STUN - Simple Traversal of User Datagram Protocol (UDP) Through Network Address Translators (NATs)

摘录自:https://blog.csdn.net/wyl1987527/article/details/80188001


摘录的图片不清楚,我也是放大好几倍,想通过图片搞清楚有点难。
先抓包看看再说

STUN服务程序(coturn)

流程挺复杂的,那么有没有现成stun服务供我们用呢?
可定有啊,coturn

摘录自:https://github.com/coturn/coturn

This project evolved from rfc5766-turn-server project (https://code.google.com/p/rfc5766-turn-server/). There are many new advanced TURN specs which are going far beyond the original RFC 5766 document. This project takes the code of rfc5766-turn-server as the starter, and adds new advanced features to it.

相关标准: RFC 5766 Traversal Using Relays around NAT (TURN): Relay Extensions to Session Traversal Utilities for NAT (STUN)

自己部署了coturn,但是好像不能用,不用能用原因应该是我的服务器只有一个公网IP,不能够完整的走完测试流程。

详情可见:https://blog.csdn.net/yjkhtddx/article/details/110117862
也是一把辛酸泪啊,不提了。

公共STUN服务

摘录自:http://www.freeswitch.org.cn/2012/01/11/gong-yong-stun-fu-wu-qi-lie-biao.html

Public STUN serversprovserver.televolution.net
sip1.lakedestiny.cordiaip.com
stun1.voiceeclipse.net
stun01.sipphone.com
stun.callwithus.com
stun.counterpath.net
stun.ekiga.net (alias for stun01.sipphone.com)
stun.ideasip.com (no XOR_MAPPED_ADDRESS support)
stun.internetcalls.com
stun.ipns.com
stun.noc.ams-ix.net
stun.phonepower.com
stun.phoneserve.com
stun.rnktel.com
stun.softjoys.com (no DNS SRV record) (no XOR_MAPPED_ADDRESS support)
stunserver.org see their usage policy
stun.sipgate.net
stun.sipgate.net:10000
stun.voip.aebc.com
stun.voipbuster.com (no DNS SRV record) (no XOR_MAPPED_ADDRESS support)
stun.voxalot.com
stun.voxgratia.org (no DNS SRV record) (no XOR_MAPPED_ADDRESS support)
stun.xten.com
numb.viagenie.ca (http://numb.viagenie.ca) (XOR_MAPPED_ADDRESS only with rfc3489bis magic number in transaction ID)
stun.ipshka.com inside UA-IX zone russsian explanation at http://www.ipshka.com/main/help/hlp_stun.php

贼多,先用别人的。

STUN客户端

找了一个,主要是星星多,看着也简单,(确实也挺简单)
https://github.com/ccding/go-stun

可以看到,我自己的电脑都是对称NAT,自己这边就没法打洞,还学个蛋蛋。
淡定,在现有条件下抓个包分析一下

抓包分析

wireshark分析抓包

wirshark配置

由于stun有重发机制,得给ID调出来,方便分析

抓包结果


抓包结果下载 http://120.53.223.230:8084/temp/stun.pcap
笔者自己私房钱偷偷整的服务器,手下留情,请勿攻击。

TEST I

第一步:

TEST II

分析

看抓包也是一头雾水,上面摘录的文章不好使,看着费劲,换一个帖子;

摘录自:https://www.csdn.net/tags/MtjacgysNzM3OTYtYmxvZwO0O0OO0O0O.html

<----------------------------------------------------------------------------------
STUN协议定义了三类测试过程来检测NAT类型,如下所述:
<----------------------------------------------------------------------------------
Test1:STUN Client通过端口{IP-c1:Port-c1}向STUN Server{IP-s1:Port-s1}发送一个Binding Request(没有设置任何属性)。STUN Server收到该请求后,通过端口{IP-s1:Port-s1}把它所看到的STUN Client的IP和端口{IP-m1,Port-m1}作为Binding Response的内容回送给STUN Client。
<----------------------------------------------------------------------------------
Test1#2:STUN Client通过端口{IP-c1:Port-c1}向STUN Server{IP-s2:Port-s2}发送一个Binding Request(没有设置任何属性)。STUN Server收到该请求后,通过端口{IP-s2:Port-s2}把它所看到的STUN Client的IP和端口{IP-m1#2,Port-m1#2}作为Binding Response的内容回送给STUN Client。
<----------------------------------------------------------------------------------
Test2:STUN Client通过端口{IP-c1:Port-c1}向STUN Server{IP-s1:Port-s1}发送一个Binding Request(设置了Change IP和Change Port属性)。STUN Server收到该请求后,通过端口{IP-s2:Port-s2}把它所看到的STUN Client的IP和端口{IP-m2,Port-m2}作为Binding Response的内容回送给STUN Client。
<----------------------------------------------------------------------------------
Test3:STUN Client通过端口{IP-c1:Port-c1}向STUN Server{IP-s1:Port-s1}发送一个Binding Request(设置了Change Port属性)。STUN Server收到该请求后,通过端口{IP-s1:Port-s2}把它所看到的STUN Client的IP和端口{IP-m3,Port-m3}作为Binding Response的内容回送给STUN Client。
<----------------------------------------------------------------------------------

分析结果


192.168.1.42:52971 → 217.10.68.152:10000 发送Binding请求
217.10.68.152:10000 → 192.168.1.42:52971 接受Binding响应
告知客户端:服务接收的Binding请求来自:117.158.134.217:49434
告知客户端:服务器的另外一个服务地址为:217.116.122.136:10001
客户端发现自己的192.168.1.42和117.158.134.217的IP不一致,
说明自己在NAT后面。


192.168.1.42:52971 → 217.10.68.152:10000 发送Binding请求,
携带参数change-ip,change_port
意思是让服务器使用217.116.122.136:10001给恢复响应消息。
但是客户端在规定的时间内,没有收到响应。
说明,客户端所在的NAT,确定不是 完全圆锥型NAT(Full Cone NAT)。


192.168.1.42:52971 → 217.116.122.136:10001 发送Binding请求,
217.116.122.136:10001 → 192.168.1.42:52971 接受Binding响应
告知客户端:服务接收的Binding请求来自:117.158.134.217:47149
告知客户端:服务器的另外一个服务地址为:217.10.68.152:10000
嗝屁,同一个端口出去的数据,因为发给不同服务器,端口不一样了。
对称型NAT(Symmetric NAT)无疑。


我这边反正是打不了洞让别人用了,
但愿对方是个 完全圆锥型NAT(Full Cone NAT)或者 地址限制圆锥型NAT(Restricted Cone NAT)
还有一丝希望通过P2P通讯。

官方说明

难搞明白的东西,有初步了解后,还是需要看看官方说明

摘录自:RFC 3489 STUN - Simple Traversal of User Datagram Protocol (UDP) Through Network Address Translators (NATs)

+--------+|  Test  ||   I    |+--------+||V/\              /\N /  \ Y          /  \ Y             +--------+UDP     <-------/Resp\--------->/ IP \------------->|  Test  |Blocked         \ ?  /          \Same/              |   II   |\  /            \? /               +--------+\/              \/                    || N                  ||                    VV                    /\+--------+  Sym.      N /  \|  Test  |  UDP    <---/Resp\|   II   |  Firewall   \ ?  /+--------+              \  /|                    \/V                     |Y/\                         /\                    |Symmetric  N  /  \       +--------+   N  /  \                   VNAT  <--- / IP \<-----|  Test  |<--- /Resp\               Open\Same/      |   I    |     \ ?  /               Internet\? /       +--------+      \  /\/                         \/|                           |Y|                           ||                           V|                           Full|                           ConeV              /\+--------+        /  \ Y|  Test  |------>/Resp\---->Restricted|   III  |       \ ?  /+--------+        \  /\/|N|       Port+------>RestrictedFigure 2: Flow for type discovery process
10.1  Discovery ProcessIn this scenario, a user is running a multimedia application whichneeds to determine which of the following scenarios applies to it:o  On the open Interneto  Firewall that blocks UDPo  Firewall that allows UDP out, and responses have to come back tothe source of the request (like a symmetric NAT, but notranslation.  We call this a symmetric UDP Firewall)o  Full-cone NATo  Symmetric NATo  Restricted cone or restricted port cone NATWhich of the six scenarios applies can be determined through the flowchart described in Figure 2.  The chart refers only to the sequenceof Binding Requests; Shared Secret Requests will, of course, beneeded to authenticate each Binding Request used in the sequence.The flow makes use of three tests.  In test I, the client sends aSTUN Binding Request to a server, without any flags set in theCHANGE-REQUEST attribute, and without the RESPONSE-ADDRESS attribute.This causes the server to send the response back to the address andport that the request came from.  In test II, the client sends aBinding Request with both the "change IP" and "change port" flagsfrom the CHANGE-REQUEST attribute set.  In test III, the client sendsa Binding Request with only the "change port" flag set.The client begins by initiating test I.  If this test yields noresponse, the client knows right away that it is not capable of UDPconnectivity.  If the test produces a response, the client examinesthe MAPPED-ADDRESS attribute.  If this address and port are the sameas the local IP address and port of the socket used to send therequest, the client knows that it is not natted.  It executes testII.If a response is received, the client knows that it has open accessto the Internet (or, at least, its behind a firewall that behaveslike a full-cone NAT, but without the translation).  If no responseis received, the client knows its behind a symmetric UDP firewall.In the event that the IP address and port of the socket did not matchthe MAPPED-ADDRESS attribute in the response to test I, the clientknows that it is behind a NAT.  It performs test II.  If a responseis received, the client knows that it is behind a full-cone NAT.  Ifno response is received, it performs test I again, but this time,does so to the address and port from the CHANGED-ADDRESS attributefrom the response to test I.  If the IP address and port returned inthe MAPPED-ADDRESS attribute are not the same as the ones from thefirst test I, the client knows its behind a symmetric NAT.  If theaddress and port are the same, the client is either behind arestricted or port restricted NAT.  To make a determination aboutwhich one it is behind, the client initiates test III.  If a responseis received, its behind a restricted NAT, and if no response isreceived, its behind a port restricted NAT.This procedure yields substantial information about the operatingcondition of the client application.  In the event of multiple NATsbetween the client and the Internet, the type that is discovered willbe the type of the most restrictive NAT between the client and theInternet.  The types of NAT, in order of restrictiveness, from mostto least, are symmetric, port restricted cone, restricted cone, andfull cone.Typically, a client will re-do this discovery process periodically todetect changes, or look for inconsistent results.  It is important tonote that when the discovery process is redone, it should notgenerally be done from the same local address and port used in theprevious discovery process.  If the same local address and port arereused, bindings from the previous test may still be in existence,and these will invalidate the results of the test.  Using a differentlocal address and port for subsequent tests resolves this problem.An alternative is to wait sufficiently long to be confident that theold bindings have expired (half an hour should more than suffice).

谁爱看谁看,我英语水平有限,我反正没有看。

P2P在什么情况下能通

摘录自(上面摘录过):https://blog.csdn.net/wgl307293845/article/details/120450626


为什么对称型NAT和端口受限型NAT之间无法实现无法实现P2P通讯

自己

悟不明白说明您没有闹懂,重新看或者再找别的帖子学习好了。

TCP怎么打洞?

和主题无关,搁置

STUN打洞学习笔记相关推荐

  1. FreeSWITCH 学习笔记(一)

    [1]FreeSWITCH学习笔记 1.Windows安装包下载地址: http://files.freeswitch.org/windows/installer/ 2.源码下载地址: http:// ...

  2. java画笔覆盖在界面_Java学习笔记:swing画笔工具Graphics,刷新页面,键盘事件,随机数等【诗书画唱】...

    Graphics:画笔工具 setColor:设置画笔颜色 DrawRect:空心矩形 fillRect:实心矩形 DrawOavl:空心圆 fillOavl:实心圆 DrawLine:画线(注意) ...

  3. 前端HTML5+CSS3学习笔记

    HTML5+CSS3学习笔记 ==CSS第一天== 一.css简介 二.css语法规范 三.css代码风格 四.css选择器的作用 五.css基础选择器 1.标签选择器: 2.类选择器 3.多类名选择 ...

  4. Redis学习笔记(B站狂神说)(自己总结方便复习)

    Redis学习笔记B站狂神说 redis: 非关系型数据库 一.NoSQL概述 1.为什么要用Nosql 1.单机Mysql的年代 思考一下,这种情况下:整个网站的瓶颈是什么? 1.数据量如果太大,一 ...

  5. 英语学习笔记(经典100句)

    [写在前面] 参考链接: 7000雅思词汇用100个句子记完!就是这么神奇! - 知乎 (zhihu.com) 本文所有的例句,来自上述链接,可直接看原文. 我这里只是学习笔记,供个人使用.如侵,请告 ...

  6. 《计算几何》学习笔记

    前言 这是学堂在线邓老师讲的<计算几何>课程的学习笔记.实际上很多细节,比如点重合.边平行等特殊情况,在课程中没有进行考虑,课程讲的算法只考虑一般性的情况. (最后两章Geometric ...

  7. Redis详细教程-学习笔记

    Redis 概述 Redis是什么? Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.K ...

  8. bootstrap学习笔记一: bootstrap初认识,hello bootstrap(下)

    这一篇主要是补上源码,开始之前请先回顾:bootstrap学习笔记一: bootstrap初认识,hello bootstrap(上) 首先,我们的页面要求, lang,charset等就不用说了,老 ...

  9. PE病毒学习笔记——初识感染技术 (转自看雪学院)

    [分享]PE病毒学习笔记--初识感染技术 <script type="text/javascript"></script>   标 题: [分享]PE病毒学 ...

最新文章

  1. Linux 指令简单将***IP列入iptables 限制范围
  2. RabbitMQ系列教程之三:发布\/订阅(Publish\/Subscribe)
  3. spark sql合并小文件_Spark SQL小文件问题在OPPO的解决方案
  4. python123测试_【测码学院】python自动化测试学习-自动化测试模型
  5. ICT学习笔记(2)网络各层次的相关内容
  6. 什么样的技术最后会成为CTO
  7. 最近学习mpvue框架开发微信小程序,把wepy框架的项目实现到mpvue中,知道其中的一些两者之间的区别...
  8. DES加密(支持ARC与MRC)
  9. wow服务器文件夹,《60级魔兽世界WTFWDB文件夹全解析 by Qcat》
  10. 修改电脑微信提示音+dll文件编辑器
  11. 廉价的新iPhoneSE会吸引哪些用户换机?
  12. 2021年全国职业院校技能大赛(中职组)网络安全竞赛试题(3)(总分100分)
  13. 虾皮台湾店标价是用台币吗?要如何定价?
  14. 动态规划问题解决方法及示例
  15. layer打开iframe弹层,传递与接收参数
  16. 机器学习数学知识(一) 自然数e
  17. 阿龙的学习笔记--- B-树和B+树 以及 MySQL的索引机制总结
  18. python实现猫捉老鼠小游戏
  19. iPhone摄像头拍照后图像旋转
  20. VVDocumenter-Xcode

热门文章

  1. 解决交叉编译连接器包含-ldl编译选项,但仍然报错undefined reference to ‘__dlsym‘
  2. 小程序实现左右箭头切换文字,点击中间文字出弹框
  3. 查看 centos 具体版本号
  4. opengl画立方体、朝向问题
  5. 支付宝蜻蜓VS微信青蛙,大佬为何抢分刷脸支付这杯羹
  6. js中报:TypeError: (intermediate value) is not a function错误
  7. java项目PC端调用条码打印机打印条码/吊牌(JS实现)
  8. 给大家分享一个选择困难症必备点餐方法吧 吃点什么好呢 早餐 午餐 晚餐
  9. 关于“不要重复造轮子”的不同看法
  10. 电视盒子怎么K歌?当贝家庭KTV音响套装助力客厅K歌