上篇讲述了什么是UDT协议,这篇来分析UDT的协议数据包的结构。
UDT协议是建于UDP协议之上的,那么其最根本的数据收发是使用UDP数据收发接口实现的:
linux下接口为:
#include < sys / socket . h >
ssize_t recvmsg ( int sockfd , struct msghdr * msg , int flags ) ;
ssize_t sendmsg ( int sockfd , struct msghdr * msg , int flags ) ;
Window下接口为:
#include <winsock2.h>
int
WSAAPI
WSASendTo(
__in SOCKET s,
__in_ecount(dwBufferCount) LPWSABUF lpBuffers,
__in DWORD dwBufferCount,
__out_opt LPDWORD lpNumberOfBytesSent,
__in DWORD dwFlags,
__in_bcount_opt(iTolen) const struct sockaddr FAR * lpTo,
__in int iTolen,
__inout_opt LPWSAOVERLAPPED lpOverlapped,
__in_opt LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);
int
WSAAPI
WSARecvFrom(
__in SOCKET s,
__in_ecount(dwBufferCount) __out_data_source(NETWORK) LPWSABUF lpBuffers,
__in DWORD dwBufferCount,
__out_opt LPDWORD lpNumberOfBytesRecvd,
__inout LPDWORD lpFlags,
__out_bcount_part_opt(*lpFromlen,*lpFromlen) struct sockaddr FAR * lpFrom,
__inout_opt LPINT lpFromlen,
__inout_opt LPWSAOVERLAPPED lpOverlapped,
__in_opt LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);
具体使用参见源码src/channel.cpp文件。
那么显然,发送UDT包时,其外层需要包裹上UDP头部,IP头部。UDT自身定义协议,来保证数据可靠性。即UDP数据包数据的长度即为UDT协议整个数据包大小,实际的应用程序数据还需再减去UDT头部长度计算得到。
UDT自定义的包分为两类:数据包和控制包。他们通过包头的第一位(标志位 )来区分,如果是0表示数据包,1表示控制包。
UDT自定义的包分为两类:数据包和控制包。他们通过包头的第一位(标志位 )来区分,如果是0表示数据包,1表示控制包。
控制包结构如下: