网络传输数据封装详解(IP,UDP,TCP)
IP数据包也叫IP报文分组,传输在ISO网络7层结构中的网络层,它由IP报文头和IP报文用户数据组成,IP报文头的长度一般在20到60个字节之间,而一个IP分组的最大长度则不能超过65535个字节。
下图为IP分组的报文头格式,报文头的前20个字节是固定的,后面的可变。
版本:占4位(bit),指IP协议的版本号。目前的主要版本为IPV4,即第4版本号,也有一些教育网和科研机构在使用IPV6。在进行通信时,通信双方的IP协议版本号必须一致,否则无法直接通信。
首部长度:占4位(bit),指IP报文头的长度。最大的长度(即4个bit都为1时)为15个长度单位,每个长度单位为4字节(TCP/IP标准,DoubleWord),所以IP协议报文头的最大长度为60个字节,最短为上图所示的20个字节。
服务类型:占8位(bit),用来获得更好的服务。其中的前3位表示报文的优先级,后面的几位分别表示要求更低时延、更高的吞吐量、更高的可靠性、更低的路由代价等。对应位为1即有相应要求,为0则不要求。
总长度:16位(bit),指报文的总长度。注意这里的单位为字节,而不是4字节,所以一个IP报文的的最大长度为65535个字节。
标识(identification):该字段标记当前分片为第几个分片,在数据报重组时很有用。
标志(flag):该字段用于标记该报文是否为分片(有一些可能不需要分片,或不希望分片),后面是否还有分片(是否是最后一个分片)。
片偏移:指当前分片在原数据报(分片前的数据报)中相对于用户数据字段的偏移量,即在原数据报中的相对位置。
生存时间:TTL(Time to Live)。该字段表明当前报文还能生存多久。每经过1ms或者一个网关,TTL的值自动减1,当生存时间为0时,报文将被认为目的主机不可到达而丢弃。使用过Ping命令的用户应该有印象,在windows中输入ping命令,在返回的结果中即有TTL的数值。
协议:该字段指出在上层(网络7层结构或TCP/IP的传输层)使用的协议,可能的协议有UDP、TCP、ICMP、IGMP、IGP等。
首部校验和:用于检验IP报文头部在传播的过程中是否出错,主要校验报文头中是否有某一个或几个bit被污染或修改了。
源IP地址:32位(bit),4个字节,每一个字节为0~255之间的整数,及我们日常见到的IP地址格式。
目的IP地址:32位(bit),4个字节,每一个字节为0~255之间的整数,及我们日常见到的IP地址格式。
由于Delphi里面没有位域这个概念,所以定义结构的时候只能整字节了,挺怀恋C++或者Erlang的,有位域定义出来和使用起来都很方便了
//IP包
TIPHeader = packed record
iph_verlen: byte; // 版本和长度
iph_tos: byte; // 服务类型
iph_length: word; // 总长度,2个无符号字节所以只能65535
iph_id: word; // 标识
iph_offset: word; // 标志和片偏移
iph_ttl: byte; // 生存时间
iph_protocol: byte; // 协议
iph_xsum: word; // 头校验和
iph_src: longword; // 源地址
iph_dest: longword; // 目的地址
end;
这个结构体有什么用呢?其实在嗅探的时候就很有用了.
TCP数据包的头
typedef struct _TCP_HEADER {
USHORT nSourPort ; // 源端口号16bit
USHORT nDestPort ; // 目的端口号16bit
UINT nSequNum ; // 序列号32bit
UINT nAcknowledgeNum ; // 确认号32bit
USHORT nHLenAndFlag ; // 前4位:TCP头长度;中6位:保留;后6位:标志位16bit
USHORT nWindowSize ; // 窗口大小16bit
USHORT nCheckSum ; // 检验和16bit
USHORT nrgentPointer ; // 紧急数据偏移量16bit
} TCP_HEADER, *PTCP_HEADER ;
UDP数据包的头
typedef struct _UDP_HEADER {
USHORT nSourPort ; // 源端口号16bit
USHORT nDestPort ; // 目的端口号16bit
USHORT nLength ; // 数据包长度16bit
USHORT nCheckSum ; // 校验和16bit
} UDP_HEADER, *PUDP_HEADER ;
进入协议栈的过程:(从协议栈出来刚好相反)
ICMP头和报文校验和的计算
////////////////////////////////定义ICMP包头
typedef struct _ICMP_HEADER {
BYTE bType ; // 类型8bit
BYTE bCode ; // 代码8bit
USHORT nCheckSum ; // 校验和16bit
USHORT nId ; // 标识,本进程ID16bit
USHORT nSequence ; // 序列号16bit
UINT nTimeStamp ; // 可选项,这里为时间,用于计算时间32bit
} ICMP_HEADER, *PICMP_HEADER ;
/////////////////////////////////
发送ICMP报文时,必须由程序自己计算校验和,将它填入ICMP头部对应的域中。校验和的计算方法是:
将数据以字(16位)为单位累加到一个双字中(强转换双字类型),如果数据长度为奇数(奇数个字节),最后一个字节将被扩展到字,累加的结果是一个双字,
最后将这个双字的高16位和低16位相加后取反,便得到了校验和!
// 计算ICMP包校验值
// 参数1:ICMP包缓冲区
// 参数2:ICMP包长度
USHORT GetCheckSum ( LPBYTE lpBuf, DWORD dwSize )
{
DWORD dwCheckSum = 0 ;
USHORT* lpWord = (USHORT*)lpBuf ;
// 累加
while ( dwSize > 1 )
{
dwCheckSum += *lpWord++ ;
dwSize -= 2 ;
}
// 如果长度是奇数
if ( dwSize == 1 )
dwCheckSum += *((LPBYTE)lpWord) ;
// 高16位和低16位相加
dwCheckSum = ( dwCheckSum >> 16 ) + ( dwCheckSum & 0xFFFF ) ;
// 取反
return (USHORT)(~dwCheckSum ) ;
}
转载地址:http://blog.163.com/tianshuai11@126/blog/static/618945432011101110497885/
网络传输数据封装详解(IP,UDP,TCP)的更多相关文章
- TCP/IP详解 IP路由选择
TCP/IP详解 IP路由选择 在本篇文章当中, 将通过例子来说明IP路由选择器过程 如图所示, 主机A与主机B分别是处在两个不同的子网当中, 中间通过一个路由连接. 如果主机A请求与主机B进行通行, ...
- Iperf3网络性能测试工具详解教程
Iperf3网络性能测试工具详解教程 小M 2020年4月17日 运维 本文下载链接 [学习笔记]Iperf3网络性能测试工具.pdf 网络性能评估主要是监测网络带宽的使用率,将网络带宽利用最大化是保 ...
- 【山外笔记-工具框架】iperf3网络性能测试工具详解教程
[山外笔记-工具框架]iperf3网络性能测试工具详解教程 本文下载链接 [学习笔记]iperf3网络性能测试工具.pdf 网络性能评估主要是监测网络带宽的使用率,将网络带宽利用最大化是保证网络性 ...
- Centos7 配置网络步奏详解
Centos7 配置网络步奏详解 编辑网卡配置文件 vi /etc/sysconfig/network-script/ifcfg-ens01 备注:这里的ens01不是所有系统都叫这个,有的可能叫其他 ...
- Android热门网络框架Volley详解[申明:来源于网络]
Android热门网络框架Volley详解[申明:来源于网络] 地址:http://www.cnblogs.com/caobotao/p/5071658.html
- CAS (6) —— Nginx代理模式下浏览器访问CAS服务器网络顺序图详解
CAS (6) -- Nginx代理模式下浏览器访问CAS服务器网络顺序图详解 tomcat版本: tomcat-8.0.29 jdk版本: jdk1.8.0_65 nginx版本: nginx-1. ...
- Linux 网络编程详解五(TCP/IP协议粘包解决方案二)
ssize_t recv(int s, void *buf, size_t len, int flags); --与read相比,只能用于网络套接字文件描述符 --当flags参数的值设置为MSG_P ...
- 第6章 传输层(详解TCP的三次握手与四次挥手)
第6章 传输层 传输层简介 传输层为网络应用程序提供了一个接口,并且能够对网络传输提供了可选的错误检测.流量控制和验证功能.TCP/IP传输层包含很多有用的协议,能够提供数据在网络传输所需的必要寻址信 ...
- 【Windows socket+IP+UDP+TCP】网络基础
Windows Socket+网络 Winsock是 Windows下套接字标准. Winsock 编程分为UDP[Windows socket + UDP],TCP[Wi ...
随机推荐
- C语言--字符串和数字的相互转换
1.数字转换为字符串 sprintf 跟printf 在用法上几乎一样,只是打印的目的地不同而已,前者打印到字符串中,后者则直接在命令行上输出. sprintf 是个变参函数,定义如下: int sp ...
- 海量数据挖掘MMDS week2: 频繁项集挖掘 Apriori算法的改进:基于hash的方法
http://blog.csdn.net/pipisorry/article/details/48901217 海量数据挖掘Mining Massive Datasets(MMDs) -Jure Le ...
- H5学习之旅-H5列表(8)
列表的基本语法 ol:有序列表 ul:无序列表 li:列表项 dl:列表 dt:列表项 dd:列表描述 常用列表 1.无序列表:使用标签 ul,li 属性:disc(默认实心圆) circle (空心 ...
- Xcode调试非异常导致崩溃的程序
如果App不是因为一个异常而崩溃,Xcode可能任然会指向main()函数为出错位置. 在这种情况下,你可能遇上了更低级别的问题.也许是一个除以0错误或是缓冲溢出问题,或者你寻址一个已经被释放的对象. ...
- 漫谈程序员(十一)老鸟程序员知道而新手不知道的小技巧之Web 前端篇
老鸟程序员知道而新手不知道的小技巧 Web 前端篇 常充电!程序员只有一种死法:土死的. 函数不要超过50行. 不要一次性写太多来不及测的代码,而是要写一段调试一段. UI和编码要同步做. 多写注释方 ...
- 【Visual C++】游戏编程学习笔记之二:定时器的使用
本系列文章由@二货梦想家张程所写,转载请注明出处. 本文章链接:http://blog.csdn.net/terence1212/article/details/44195831 作者:ZeeCode ...
- C++ 传参时传内置类型时用传值(pass by value)方式效率较高
来源:唐磊的个人博客<C++ 传参时传内置类型时用传值(pass by value)方式效率较高> 在<Effective C++>里提到对内置(C-like)类型在函数传参时 ...
- RedHat系列软件管理(第二版) --源码包安装
RedHat系列软件管理 --源码包安装 源码包特点: 拥有广泛的平台支持性,可以装在所有的类UNIX操作系统上,不用考虑CPU架构. 灵活性,可以在安装过程中指定特有的选项. 定制度非常高,可以自己 ...
- mysql 无法插入中文
MySQL数据库默认编码已经是utf8了, default-character-set = utf8,可是向数据库中表中插入中文时,却老是出现 ....\xB5\xA5\xD1\xA1 for col ...
- EventQueue.invokeLater(new Runnable())
public class EventQueueextends ObjectEventQueue 是一个与平台无关的类,它将来自于底层同位体类和受信任的应用程序类的事件列入队列. 它封装了异步事件指派机 ...