网络编程day04/05原始套接字
1.原始套接字概述
在网络编程中,套接字(socket)是一种用于实现网络通信的编程接口。原始套接字(Raw
Socket)是一种特殊的套接字类型,与普通的流式套接字和数据报套接字不同,它允许程序直接访问底层的网络协议,而不仅仅是传输层协议(如TCP和UDP)。
原始套接字的主要特点和用途包括:
- 访问底层协议:可以直接操作 IP 层及以下的协议,例如构造和发送自定义的 IP 数据包、分析网络数据包等。
- 网络监测和分析:用于实现网络嗅探器(Sniffer),捕获和分析网络中的数据包,了解网络通信的细节。
- 自定义协议实现:可以实现自定义的网络协议,用于特殊的网络应用场景。
原始套接字是基于【数据链路层】实现。
2.UDP TCP IP协议底层结构
2.1数据打包方式
2.2UDP协议数据包格式
字段 | 长度(位) | 说明 |
源端口号 | 16 | 发送方的端口号 |
目的端口号 | 16 | 接收方的端口号 |
长度 | 16 | UDP数据包(包括首部和数据)的长度,以字节为单位。 |
校验和 | 16 | 用于校验UDP数据包的完整性 |
struct udphdr {__be16 source; // __be16 ==> unsigned short__be16 dest;__be16 len;__sum16 check; // __sum16 ==> unsigned short
};
2.3TCP协议数据包格式
字段 | 长度 | 说明 |
源端口号 | 16 | 发送方端口号 |
目的端口号 | 16 | 接收方端口号 |
序列号 | 32 | 用于标识数据包在数据流中的位置 |
确认号 | 32 | 用于确认已收到的数据包 |
数据偏移 | 4 | 表示TCP首部的长度,以32未(4字节)为单位 |
保留 | 6 | 保留字段,必须设置为0 |
控制位 | 6 | 包含多个控制标志,如SYN,ACK,FIN等 |
窗口大小 | 16 | 表示接收方的接受窗口大小 |
校验和 | 16 | 用于校验TCP数据包的完整性 |
紧急指针 | 16 | 用于指针紧急数据的位置 |
选项 | 可变 | 可选字段,用于提供额外的功能 |
struct tcphdr {
u_int16_t th_sport; /* 源端口号 */
u_int16_t th_dport; /* 目的端口号 */
tcp_seq th_seq; /* 序列号 */
tcp_seq th_ack; /* 确认号 */
u_int8_t th_offx2; /* 首部长度和保留位 */
u_int8_t th_flags; /* TCP 标志位 */
u_int16_t th_win; /* 窗口大小 */
u_int16_t th_sum; /* 校验和 */
u_int16_t th_urp; /* 紧急指针 */
};
2.4IP协议数据包格式
字段 | 长度 | 说明 |
版本 | 4 | 指示IP协议的版本,通常为IPv4(值为4)或IPv6(值为6)。 |
首部长度 | 4 | 表示IP首部的长度,以32位(4字节)为单位。 |
服务类型 | 8 | 用于指示数据包的优先级和服务类型。 |
总长度 | 16 | 整个IP数据包(包括首部和数据)的长度,以字节为单位。 |
标识 | 16 | 用于唯一标识一个IP数据包,主要用于分片和重组。 |
标志 | 3 | 包含三个标志位,用于控制分片操作。 |
片偏移 | 13 | 指示该片在原始数据包中的相对位置。 |
生存时间 | 8 | 限制数据包在网络中的生存时间,每经过一个路由器,TTL值减1,TTL为0时,数据包被丢弃。 |
协议 | 8 | 指示上层协议的类型,如TCP(值为6),UDP(值为17)等 |
首部校验和 | 16 | 用于校验IP首部的完整性 |
源IP地址 | 32 | 发送方的IP地址 |
目的IP地址 | 32 | 接收方的IP地址 |
选项 | 可变 | 可选字段,用于提供额外的功能 |
struct iphdr{
#if defined(__LITTLE_ENDIAN_BITFIELD)
__u8 ihl:4,
version:4;
#elif defined (__BIG_ENDIAN_BITFIELD)
__u8 version:4,
ihl:4;
#else
#error "Please fix <asm/byteorder.h>"
#endif
__u8 tos;
__be16 tot_len;
__be16 id;
__be16 frag_off;
__u8 ttl;
__u8 protocol;
__sum16 check;
__be32 saddr;
__be32 daddr;
/* 选项从此处开始 */
}