libutp是uTorrent使用的类似TCP的传输层实现。它基于UDP提供可信的、有序的点对点的传输,并具有最少的时延。需要注意的是utp和另一个基于UDP的传输协议QUIC的实现思路和优势并不一样,例如QUIC更强调连接建立的快速性,建立连接时只需要1至2次握手,又如QUIC将TLS整合到协议中,实现了0RTT,而基于HTTP2的协议需要2/3RTT。QUIC还允许在用户层面配置各种拥塞控制算法。
网上有关libutp实现的介绍几乎没有,因此我打算就其源码做一个简单的分析。这里要注意UTP是基于包的而不像TCP是基于流的,虽然它提供的API还是基于流的。这样有一些影响,例如黏包问题的处理、缓冲区的管理(例如可以去掉PUSH标记)、窗口管理、重新分组等方面。
uTP源码简介
utp.h以 C89 的形式提供接口。例如 utp_write
是以 proactive 的方式实现的。
utp 相关的实现大多在 utp_internal.cpp 文件中。
utp_packedsockaddr.cpp 中封装了 sockaddr_in
结构。
ucat.c 基于 uTP 框架构建了一个基础的应用。
uTP 的设计主要是异步的,应用代码不会阻塞在异步 IO 操作上,而是指定回调函数并立即返回。utp_callbacks.cpp中注册了各种回调函数,utp 向外界传输消息都是以这里回调的形式开展的。例如当收到数据包时,ctx->callbacks[UTP_ON_READ]
这个回调函数就会被调用。