在平时的开发工作中,我们都使用被封装完好的 TCP/HTTP 库去完成需求开发,很少关心底层 TCP 的连接状态,但是一旦遇到较难定位的线上事故,往往都是因为 TCP 连接参数或者使用姿势不对导致的,本文对 TCP 连接状态以及相关命令做一下梳理总结:

什么是 TCP 协议

  • 位于 OSI 模型中的传输层(第四层),是一种端对端的传输协议
  • 面向连接的、可靠的协议
  • 通过校验和、序列号、确认应答、重发控制、窗口控制等机制实现可靠传输
  • 由建立连接、数据传输和连接释放三个阶段组成
  • 采用三次握手建立连接,采用四次挥手关闭连接

想了解 TCP 的连接状态,必须先理清楚 TCP 的三次握手和四次挥手是怎么回事,下图关于 TCP 三次握手和四次挥手的状态转换图(图片来自于知乎文章 《“三次握手,四次挥手”你真的懂吗?》):

这里不要把图里的 Client/Server 和项目里的客户端服务器端混淆,主动发起连接的一方或者主动关闭连接的一方就是 Client,被动的一方便为 Server。一个服务既可以充当 Client 的角色,也可以充当 Server 的角色。

TCP 的三次握手

三次握手为了使 Client 和 Server 都确认是否有接受对方的数据和发送数据给对方的能力:

  • 第一次握手:Client 先发送一个 SYN(j) 包作为建立连接的请求,确认自己的发送能力是否正常
  • 第二次握手:Server 针对 Client 的 SYN 包回复一个 ACK(j + 1) 包确认应答,同时发送 SYN(k) 包给 Client 表示要求建立连接,在明确自己有接收能力的同时确认一下自己的发送能力
  • 第三次握手:Client 收到 SYN + ACK 包后发送 ACK(k + 1) 包确认应答,表示自己的接收能力正常,此时完成三次握手建立可靠的连接

TCP 的四次挥手

四次挥手主要是为了让 Client 和 Server 双方都可以正常关闭连接,保证关闭连接前不丢失数据:

  • 第一次挥手:Client 先发送一个 FIN 包表示请求断开连接
  • 第二次挥手:当 Server 收到 FIN 包后,立即回复 ACK 进行确认应答,表示我已经收到你关闭连接的请求,此时 Server 还有接收数据的能力
  • 第三次挥手:一段时间后,当 Server 端确认 Client 端的数据已经接受完毕,发送一个 FIN 包表示关闭连接,不再接收数据
  • 第四次挥手:当 Client 收到 FIN 后,立即回复一个 ACK 进行确认,然后等待 2MSL 后关闭连接

TCP 的连接状态

在 TCP 的三次握手、数据传输以及四次挥手的过程中,我们给 Client 和 Server 定义了很多状态用于描述整个流程,结合上面的状态转换图来理解这些状态定义:

  • LISTEN(Server): 正在侦听来自远方的 TCP 端口的连接请求,服务端启动后处于 LISTEN 状态用于监听不同客户端的 TCP 请求并建立连接
  • SYN-SENT(Client): 三次握手时,Client 在发送 SYN 以请求后处于等待建立连接的状态
  • SYN_RCVD(Server):三次握手时,当 Server 收到 Client 的 SYN 信号时,将标志位 ACK 和 SYN 发送给 Client 后到建立连接之间,Server 处于 SYN_RCVD 状态
  • ESTABLISHED(Server And Client):三次握手成功以后,Client 和 Server 处于数据传输的状态
  • FIN-WAIT-1(Client):四次挥手时,Client 端发送中断请求 FIN 到收到 Server 端的中断确认的过程
  • CLOSE_WAIT(Server):四次挥手时,Client 接收到 Client 的 FIN 请求响应后回复 ACK 确认到发送 FIN 包的状态
  • FIN-WAIT-2(Client):四次挥手时,当 Client 接收到 Server 对于 FIN 的响应 ACK 后到收到 Server 端的 FIN 包的状态
  • LAST_ACK(Server):四次挥手时,Server 发送 FIN 请求关闭连接到关闭连接前的状态
  • TIME_WAIT(Client):四次挥手时 Client 对于 Server 的 FIN 回复 ACK 到连接关闭前的状态,又称 2MSL 状态
  • CLOSE(Server And Client):Server 和 CLient 关闭连接后的状态

正常情况下,客户端的状态转换流程如下:

CLOSED -> SYN_SENT -> ESTABLISHED -> FIN_WAIT_1 -> FIN_WAIT_2 -> TIME_WAIT -> CLOSED

正常情况下,服务端的状态转换流程如下:

CLOSED -> LISTEN -> SYN_RCVD -> ESTABLISHED -> CLOSE_WAIT -> LAST_ACK -> CLOSED

关于 TCP 三次握手和四次挥手状态转换中的一些问题

  • 什么是 MSL ?
- MSL 全称是 maximum segment lifetime,报文最大生存时间
- MSL 是任何 IP 数据报能够在因特网存活的最长时间,超过这个时间报文将被丢弃
- MSL 的具体值通常为 30 秒或者是 2 分钟

  • 什么是 TTL ?
- TTL(time to live) 通常表示在数据传输中,包在被丢弃前最多能经过的路由器个数
- 每经过一个路由器都至少要把 TTL 减 1,当记数到 0 时,路由器决定丢弃该包,并发送一个 ICMP 报文给最初的发送者(表示不可达)
- TTL 是由发送主机设置的,以防止数据包不断在 IP 互联网络上永不终止地循环
- TTL 的值可以修改,但是不能超过 256,一般是 64,128...
- ping 命令返回的 TTL 值表示当包达到目标主机时,还剩下的 TTL 值,所以假设系统 TTL 值是 64,ping 出来的 TTL 结果是 58,那么从源主机到达目标主机需要经过 64 - 58 = 6 次跳转
- traceroute 在追踪网络数据包传输路由时,也可以通过参数 -m 指定 TTL,表示经过的网关最大数量

  • 什么是 RTT ?
- RTT 是客户到服务器往返所花时间(round-trip time,简称RTT)
- TCP 含有动态估算 RTT 的算法,TCP 还持续估算一个给定连接的 RTT,因为 RTT 受网络传输拥塞程序的变化而变化

  • 什么是 MTU ?
- Maximum Transmit Unit(最大传输单元),即物理接口(数据链路层)提供给其上层最大一次传输数据的大小
- 每个网络接口都可以设置自己的 MTU 值,默认值一般为 1500,表示整个 IP 包从这个接口最大可以发送 1500 个字节
- 因为一般情况下 IP 层传输的数据大于 MTU 值,需要需要采用分片技术进行传输
- 路径 MTU:任意两台主机之间的 MTU 不一定相同,因为数据在传输中会经过多台主机,需要找出所有路径中最小的 MTU(路径 MTU)进行传输否则数据传输会失败,一般通过 ICMP 协议进行路径 MTU 的发现

  • 什么是 MSS ?
- Maximum Segment Size(最大分段大小), 不包含 TCP Header 和 TCP Option,只包含 TCP Payload
- MSS 是 TCP 用来限制应用层最大的发送字节数,如果底层物理接口 MTU = 1500 byte,则 MSS = 1500- 20(IP Header) -20 (TCP Header) = 1460 byte

  • 为什么建立连接协议是三次握手,而关闭连接却是四次挥手呢?
主要是因为建立连接之前双方都没有任何数据传输发生,双方处于干净的状态,所以 Server 可以直接把 ACK 和 SYN 放在一个数据包里发送到 Client,
少一次数据传输的过程。而四次挥手时,Client 发送了 FIN 报文,仅仅表示 Client 已经没有数据要发送给 Server 了,但是 Client 仍然可以接受数据,
所以当 Server 收到 Client 数据的 FIN 报文后,它可以对于 FIN 请求进行应答(ACK),但是不能同时发送 FIN 也请求关闭连接,因为此时可能存在没有
传输完的数据,而一旦发送 FIN 报文就意味着要停止发送数据,所以需要等待数据传输完再发送 FIN 报文,因此需要四次挥手。

  • 四次挥手时,Client 完成对于 Server 的 ACK 后为什么不立即关闭连接,要存在一个 TIME_WAIT(2MSL) 状态?
之所以要等待这个状态主要有两个原因:
- 最后一次挥手数据很有可能丢失,维持这个状态主要为了可以继续重发 ACK
- 因为 TCP 发送出去的包和接收到的包顺序不一定保持一致,如果 Server 先发出去的包延迟到达后,Client 将收不到,并且会干扰新建立的连接

  • 如果服务器上存在大量 TIME_WAIT 情况,如何改善?
如果出现 TIME_WAIT 状态一般因为客户端频繁的建立和关闭连接,从而可能影响后续连接的建立,这种情况一般可以通过调节系统参数优化,修改这些参数要慎重:
- tcp_tw_recycle:表示开启 TCP 连接中 TIME-WAIT sockets 的快速回收
- tcp_tw_reuse:表示开启重用。允许将 TIME-WAIT sockets 重新用于新的 TCP 连接
- tcp_max_tw_buckets:指定系统在同一时间最多能有多少 TIME_WAIT 状态,当超过这个值时,系统会直接干掉 TIME_WAIT 的 socket

  • 如果服务器上存在大量 CLOSE_WAIT 情况,如何改善?
- 存在大量 CLOSE_WAIT 状态一般都是自身代码的原因,所以首先还是从自身的代码出发,不要随便甩锅
- 一般是因为服务器调用第三方应用(mysql, redis等)时,处理完结果忘记关闭连接,导致第三方应用因为超时发起主动关闭,而服务器无响应进而出现大量 CLOSE_WAIT 状态
- 例如在 mysql 连接过程中,sql 回滚或者提交时忘记关闭与 mysql 的连接,导致 mysql 因为超时主动关闭连接,就会大量 CLOSE_WAIT 的状态
- 例如在 javascript 中同步和异步代码乱用,导致处理完请求后无法回调错误引起超时

SYN FLOOD 攻击

  • 什么是 SYN FLOOD 攻击:

在进行三次握手时,攻击软件向被攻击的服务器发送 SYN 连接请求(三次握手的第一步),但是客户端的地址是伪造的,服务器在收到连接请求时将标志位 ACK 和 SYN 发送给客户端(三次握手的第二步),但是由于这些客户端的 IP 地址都是伪造的,服务器根本找不到客户端,导致出现大量握手失败的情况。这种情况下服务器端一般会选择重试(再次发送 SYN+ACK 给客户端)并等待一段时间后丢弃这个未完成的连接,这段时间的长度我们称为 SYN Timeout,服务器端将为了维护一个非常大的半连接列表而消耗非常多的资源,消耗非常多的 CPU 时间和内存,可能导致服务器失去响应,SYN FLOOD 攻击就达到目的。

  • 如何防御 SYN FLOOD 攻击:
1. 可以减少半开状态下等待 ACK 消息的时间
2. 减少重试发送 SYN-ACK 消息的次数
3. 部署支持“ IP 防伪”的路由器,将伪造过 IP 地址的 SYN 消息直接过滤掉
4. SYN Cache:分多个 SYN 缓存 Bucket,进入每个 Bucket 是随机的,每个 bucket 处于 SYN 的连接个数有限,超过限制就踢出先加入的 SYN 连接,攻击者很难均匀填满所有 Bucket
5. SYN Cookies:服务端通过特定的算法把半开连接信息编码成 “Cookie”,用作服务端给客户端的消息编号(SequenceNum),随 SYN-ACK消息一同返回给连接发起方客户端,这样在连接完全建立前服务端不保存任何信息。也不用一直等待,缺点是服务端丧失了重发 SYN-ACK 的能力

关于 Socket

  • 一个 TCP 连接对应一个 Socket
  • 一个 Socket 的唯一标识是: {SRC-IP, SRC-PORT, DEST-IP, DEST-PORT, PROTOCOL}
  • 一个处于监听状态的 TCP 服务可以同时接口来自多个客户端的 Socket
  • 不同进程可以监听同一个端口,如果他们的协议(TCP/UDP)不同
  • 一个进程可以打开和关闭多个 Socket
  • 子进程可以继承所有的文件描述符(FD)从父进程上,所以不同的进程或者线程之间如果有父子关系,可以使用同一个Socket
  • 一个处于监听状态的 TCP 服务只需要一个监听端口,但可以建立多个 Socket
  • 服务器一个端口可以创建的 socket 连接数理论上是没有上限的,取决于系统的内存大小和可以创建的文件描述符的上限,可以通过修改文件描述符上限进行设置

TCP 连接中的相关命令

netstat 命令

netstat 用于打印网络连接、路由表、连接的数据统计等,我们上文中介绍的各种连接状态都可以通过该命令进行统计

  • 参数介绍
- -a:列出所有状态的连接
- -l:列出正在监听状态(State=LISTEN的连接
- -t:列出所有 tcp 协议的连接
- -u:列出所有 udp 协议的连接
- -n: 开启域名解析,将对应的域名解析为 IP
- -p:列出正在监听的进程名称和进程 PID(PID/Program name),在 root 用户下启动的进程,普通用户是查不到对应的进程名称的
- -e:列出进程对应的用户 ID 或者用户(USER),是用户 ID 还是用户名由 -n 参数决定
- -s:打印每种协议网络包统计数据
- -r:打印内核路由信息
- -i:打印网络接口信息,同 ifconfig 命令

  • 列出所有 tcp 的连接:
$ netstat -antActive Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 127.0.0.1:15778         0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:514             0.0.0.0:*               LISTEN
tcp        0      0 10.122.139.165:62411    10.199.136.43:80        ESTABLISHED
tcp        0      0 106.2.124.34:443        115.236.119.139:39120   ESTABLISHED
...

  • 只列出处于监听状态的连接:
$ netstat -tnlActive Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 127.0.0.1:15778         0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:514             0.0.0.0:*               LISTEN
...

  • 查看监听中的进程名和用户名
$ netstat -tnl(Not all processes could be identified, non-owned process infowill not be shown, you would have to be root to see it all.)
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       User       Inode       PID/Program name
tcp        0      0 localhost:15778         *:*                     LISTEN      root       538503951   -
tcp        0      0 *:shell                 *:*                     LISTEN      root       509846560   -
tcp        0      0 localhost:15779         *:*                     LISTEN      root       538504573   -

  • 查看网络接口:

和 ifconfig 和 ip a 的效果一样

$ netstat -ie

  • 统计 TCP 每个连接状态信息:
$ netstat -n | awk `/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}`LAST_ACK 5
SYN_RECV 30
ESTABLISHED 15
FIN_WAIT1 51
FIN_WAIT2 5
TIME_WAIT 10

ping 命令

ping 命令用于测试到达目的主机的网络是否可用,可以接收域名或者 ip,不能检查端口,工作在 OSI 参考模型的第三层-网络层

ping 命令和 traceroute 命令一样都是通过 ICMP 协议实现的,尽管 ping 工具也可以进行侦测,但是因为 ip 头的限制,ping 不能完全的记录下所经过的路由器。所以 traceroute 正好就填补了这个缺憾,所以如果想查询整个路由信息还是需要 traceroute

# 直接 ping ip
$ ping 10.165.124.134
PING 10.165.124.134 (10.165.124.134): 56 data bytes
64 bytes from 10.165.124.134: icmp_seq=0 ttl=63 time=3.923 ms
64 bytes from 10.165.124.134: icmp_seq=1 ttl=63 time=4.103 ms# ping域名,可以获取到指定域名的 ip
$ ping dev.youdata.com
PING dev.youdata.com (106.2.44.33): 56 data bytes
64 bytes from 106.2.44.33: icmp_seq=0 ttl=58 time=3.477 ms
64 bytes from 106.2.44.33: icmp_seq=1 ttl=58 time=3.904 ms
64 bytes from 106.2.44.33: icmp_seq=2 ttl=58 time=3.878 ms// -c 参数指定发送包的个数
$ ping -c 2 dev.youdata.com// -W 参数指定 ping 命令的等待时间
$ ping -W 2 dev.youdata.com

traceroute 命令

raceroute 原理是利用 ICMP 的 ttl expired 通知机制,每次通过不断增加 ttl 从而不断发现下一跳路由,traceroute 发送的是端口号 > 30000 的数据报,所以到达目的主机的时候,会收到端口不可达的 ICMP 回应,这个时候源主机就知道主机可以连通了。

$ traceroute www.baidu.com
traceroute to www.baidu.com (61.135.169.125), 30 hops max, 40 byte packets1  192.168.74.2 (192.168.74.2)  2.606 ms  2.771 ms  2.950 ms2  211.151.56.57 (211.151.56.57)  0.596 ms  0.598 ms  0.591 ms3  211.151.227.206 (211.151.227.206)  0.546 ms  0.544 ms  0.538 ms4  210.77.139.145 (210.77.139.145)  0.710 ms  0.748 ms  0.801 ms5  202.106.42.101 (202.106.42.101)  6.759 ms  6.945 ms  7.107 ms6  61.148.154.97 (61.148.154.97)  718.908 ms * bt-228-025.bta.net.cn (202.106.228.25)  5.177 ms7  124.65.58.213 (124.65.58.213)  4.343 ms  4.336 ms  4.367 ms8  202.106.35.190 (202.106.35.190)  1.795 ms 61.148.156.138 (61.148.156.138)  1.899 ms  1.951 ms9  * * *
30  * * *

  • raceroute 命令可以让你实现追踪网络数据包的路由途径,以及每个网关消耗的时间,预设数据包大小是 40 Bytes
  • raceroute 输出结果会看到有一些行是以星号表示的记录,可能是因为防火墙封掉了 ICMP 的返回信息,所以我们得不到什么相关的数据包返回数据
  • 每次数据包由某一同样的出发点(source)到达某一同样的目的地(destination)走的路径可能会不一样,但基本上来说大部分时候所走的路由是相同的
  • 每个跳跃点默认情况下会发送 3 次数据包,但是不一定会是同一个 ip,因为两个网关之间也有可能有负载均衡策略,所以有些记录中可能会有 2 个或者 3 个 ip
  • ip 头所能纪录的路由列表是非常有限的,所以 traceroute 采取不断增加 ttl 的方式去发送,这也正是 traceroute 越到后面记录返回越慢的原因
  • 主要参数说明:
-q: 探测数据包向每个网关发送数据包的个数,默认是 3 次,会记录每次的时间长度
-m: 设置数据包经过网关的最大个数(TTL)
-n: 显示 ip,不查主机名

lsof 命令

lsof(list open files)是一个查看当前系统文件的工具。在 linux 环境下,任何事物都以文件的形式存在,通过文件不仅仅可以访问常规数据,还可以访问网络连接和硬件。例如传输控制协议 (TCP) 和用户数据报协议 (UDP) 套接字等,系统都会在后台都为该应用程序分配了一个文件描述符,该文件描述符提供了大量关于这个应用程序本身的信息。

  • 参数说明
- -a: 列出打开文件存在的进程查找某个文件相关的进程
- -c<进程名>: 列出指定进程所打开的文件
- -g:列出GID号进程详情
- -d<文件号>: 列出占用该文件号的进程
- +d<目录>: 列出目录下被打开的文件
- +D<目录>: 递归列出目录下被打开的文件
- -n<目录>: 列出使用NFS的文件
- -i<条件>: 列出符合条件的进程。(4、6、协议、:端口、 @ip )
- -p<进程号>: 列出指定进程号所打开的文件
- -u: 列出UID号进程详情
- -h: 显示帮助信息
- -v: 显示版本信息

  • 查找某个文件相关的进程
$ lsof /bin/bash

  • 列出某个用户打开的文件信息
$ lsof -u username

  • 列出某个程序进程所打开的文件信息
$ lsof -c mysql

  • 通过某个进程号显示该进程打开的文件
$ lsof -p 11968

  • 列出所有 tcp 网络连接信息
$ lsof -i tcp

  • 列出某个端口被哪个进程占用
$ lsof -i :3306

telnet 命令

  • telnet 命令用于登录远程主机
  • telnet 因为采用明文传送报文,安全性不好,很多 Linux 服务器都不开放 telnet 服务,而改用更安全的 ssh 方式
  • telnet 位于 OSI 模型的第七层(应用层)的一种协议
  • telnet ip port 用于测试远程主机的某个端口是否开放,而 ping 命令是测试远程主机网络是否能通

参考文献

  • 线上大量CLOSE_WAIT的原因深入分析
  • 又见CLOSE_WAIT
  • 再叙TIME_WAIT
  • 每天一个linux命令(55):traceroute命令
  • ping 原理与ICMP协议
  • netstat 的10个基本用法
  • 什么是SYN Flood攻击?
  • 由 socket 的 accept 说开去
  • How do multiple clients connect simultaneously to one port, say 80, on a server? [duplicate]
  • TCP 连接的状态详解以及故障排查
  • lsof 一切皆文件

连接状态_TCP 连接状态及相关命令学习相关推荐

  1. 请使用命令行统计各tcp状态的数量_TCP 连接状态及相关命令学习

    在平时的开发工作中,我们都使用被封装完好的 TCP/HTTP 库去完成需求开发,很少关心底层 TCP 的连接状态,但是一旦遇到较难定位的线上事故,往往都是因为 TCP 连接参数或者使用姿势不对导致的, ...

  2. TCP 连接状态及相关命令学习

    在平时的开发工作中,我们都使用被封装完好的 TCP/HTTP 库去完成需求开发,很少关心底层 TCP 的连接状态,但是一旦遇到较难定位的线上事故,往往都是因为 TCP 连接参数或者使用姿势不对导致的, ...

  3. java tcp 获取状态_TCP连接状态

    服务端,端口的状态变化 先在本机(IP地址为:192.168.1.10)配置FTP服务,然后在其它计算机(IP地址为:192.168.1.1)访问FTP服务,从TCPView看看端口的状态变化. 下面 ...

  4. Linux_相关命令(学习,备忘)

    1.Linux 查看实时cpu使用率: top 说明:top命令即时显示process的动态 2.查看cpu处理器使用率: cat /proc/stat 3.平均cpu使用率 4.赋予文件夹下所有文件 ...

  5. OpenSSL 之 RSA 相关命令学习笔记

    2019独角兽企业重金招聘Python工程师标准>>> 作者: Angus.Fenying <i.am.x.fenying@gmail.com> 日期: 2016-11- ...

  6. socket相关命令

    socket相关命令 学习<Linux高性能服务器编程>第五章Linux网络编程基础API,为了印象深刻一些,多动手多实践,所以记下这个笔记.这一篇主要记录Linux中socket相关的命 ...

  7. go 监测tcp 连接断开_TCP三次握手和四次挥手以及11种状态

    三次握手 置位概念:根据TCP的包头字段,存在3个重要的标识ACK.SYN.FIN ACK:表示验证字段 SYN:位数置1,表示建立TCP连接 FIN:位数置1,表示断开TCP连接 三次握手过程说明: ...

  8. tcp假连接_ESTABLISHED状态的连接收到 SYN 会回复什么?

    通过阅读这篇文章,你会了解到这些知识 ESTABLISHED 状态的连接收到乱序包会回复什么 Challenge ACK 的概念 ACK 报文限速是什么鬼 SystemTap 工具在 linux 内核 ...

  9. PHP连接redis并执行redis相关命令的方法详解

    PHP连接redis并执行redis相关命令的方法详解 连接redis库的方法 共性的运算归类 redis服务类函数 set 操作增删改查 List栈的结构,注意表头表尾,创建更新分开操作 Set,没 ...

最新文章

  1. Shape Drawable
  2. Kafka设计解析(二):Kafka High Availability (上)-转
  3. 【手写系列】透彻理解MyBatis设计思想之手写实现
  4. CF407 E. k-d-sequence
  5. PKU 1061 青蛙的约会
  6. mobaxterm用alt键作为meta键的方法
  7. 任务型对话(一)—— NLU/SLU(意识识别和槽值填充)
  8. 机器视觉之镜头景深概念与计算
  9. 视图:定义视图 (建立视图、删除视图格式、查询视图、更新视图、视图的作用)
  10. 啮齿类动物大尺度功能网络
  11. android下载通知栏,Android开发中实现下载文件通知栏显示进度条
  12. Power bi 4.14 桑基图
  13. 二手苹果手机哪个性价比高?
  14. 虚拟机下载安装Centos7(新手详解)
  15. 微信小程序 - image 宽高自适应(图片无法自适应撑开标签)
  16. 计算机科学速成课学习
  17. 真正借奥运雄起只有无线互联网
  18. 鸢尾花(iris)数据集分析
  19. sqli-labs/Less-49
  20. 公文识别SDK开发包

热门文章

  1. python中的raw string的使用
  2. PowerBuilder程序 ASA 数据库移植后不能连接解决
  3. spark,hadoop区别
  4. 协程和任务 异步IO 重点
  5. DLPack构建跨框架的深度学习编译器
  6. NVIDIA GPU上的随机数生成
  7. MindArmour差分隐私
  8. Anchor Boxes示例实战
  9. 二分查找模板全面总结
  10. 2021年大数据ELK(八):Elasticsearch安装IK分词器插件