UDP与IP分片

UDP与IP分片

一、UDP

1. UDP特点

udp-ip-split-1

它不提供差错纠正队列管理重复消除流量控制拥塞控制。它提供差错检测,包含我们在传输层中碰到的第一个真实的端到端(end-to-end)校验和。

我们可能考虑到这种可靠性和保护性的缺失,而会一般认为使用UDP一点好处也没有。但是,这是不对的。因为它的无连接特征,它要比其他的传输协议使用更少的开销。UDP请求头只有8字节,一般的IP协议请求头20字节,TCP协议请求头20字节,更少的开销意味着更高的效率。另外,广播和组播操作更多直接使用像UDP这样的无连接传输。

2. UDP校验和

UDP校验和是我们遇到的第一个端到端传输层校验和。什么是端到端:它由初始的发送方计算得到,由最终的目的方校验。

对比ICMP协议有一个端到端的校验和,因为它不传输数据,只提供诊断和控制信息。而且它既不是

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的C语言实现IP分片和重组的示例代码,仅供参考: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdint.h> #define IP_HEADER_LEN 20 // IP header length #define MAX_PACKET_LEN 65535 // maximum packet length typedef struct ip_header { uint8_t ver_ihl; // Version (4 bits) + Internet header length (4 bits) uint8_t tos; // Type of service uint16_t total_len; // Total length uint16_t id; // Identification uint16_t frag_off; // Fragment offset field uint8_t ttl; // Time to live uint8_t protocol; // Protocol uint16_t checksum; // Header checksum uint32_t src_addr; // Source address uint32_t dest_addr; // Destination address } ip_header_t; void fragment_packet(uint8_t *packet, uint32_t len, uint32_t mtu) { // check packet length if (len > MAX_PACKET_LEN) { printf("Packet is too long!\n"); return; } // check MTU if (mtu < IP_HEADER_LEN + 8) { printf("MTU is too small!\n"); return; } // calculate number of fragments uint32_t num_frags = (len + mtu - 1) / mtu; if (num_frags > 65535) { printf("Too many fragments!\n"); return; } // create IP header for each fragment ip_header_t *headers[num_frags]; for (uint32_t i = 0; i < num_frags; i++) { headers[i] = malloc(IP_HEADER_LEN); memset(headers[i], 0, IP_HEADER_LEN); ip_header_t *header = headers[i]; header->ver_ihl = 0x45; // IPv4, 5 * 4 = 20 bytes header length header->total_len = htons(mtu); header->id = htons((uint16_t) rand()); header->frag_off = htons(i * (mtu - IP_HEADER_LEN) / 8); if (i == num_frags - 1) { header->frag_off |= htons(0x2000); // last fragment } header->ttl = 64; header->protocol = 17; // UDP header->src_addr = 0x0100007f; // localhost header->dest_addr = 0x0100007f; // localhost // calculate header checksum uint32_t sum = 0; for (int j = 0; j < IP_HEADER_LEN; j += 2) { sum += ((uint16_t) header[j]) << 8 | header[j + 1]; } while (sum >> 16) { sum = (sum & 0xffff) + (sum >> 16); } header->checksum = htons(~sum); } // fragment packet uint32_t offset = 0; for (uint32_t i = 0; i < num_frags; i++) { uint32_t frag_len = mtu - IP_HEADER_LEN; if (offset + frag_len > len) { frag_len = len - offset; } memcpy(headers[i] + IP_HEADER_LEN, packet + offset, frag_len); offset += frag_len; } // send fragments for (uint32_t i = 0; i < num_frags; i++) { ip_header_t *header = headers[i]; uint32_t frag_len = ntohs(header->total_len); uint8_t *fragment = malloc(frag_len); memcpy(fragment, header, IP_HEADER_LEN); memcpy(fragment + IP_HEADER_LEN, header + IP_HEADER_LEN, frag_len - IP_HEADER_LEN); printf("Sending fragment %d...\n", i); // send fragment over network free(fragment); } // free headers for (uint32_t i = 0; i < num_frags; i++) { free(headers[i]); } } void reassemble_packet(ip_header_t **headers, uint32_t num_frags) { uint32_t packet_len = 0; for (uint32_t i = 0; i < num_frags; i++) { packet_len += ntohs(headers[i]->total_len) - IP_HEADER_LEN; } uint8_t *packet = malloc(packet_len); uint32_t offset = 0; for (uint32_t i = 0; i < num_frags; i++) { uint32_t frag_len = ntohs(headers[i]->total_len) - IP_HEADER_LEN; memcpy(packet + offset, headers[i] + IP_HEADER_LEN, frag_len); offset += frag_len; } printf("Reassembled packet:\n"); // process reassembled packet free(packet); } int main() { srand(time(NULL)); uint8_t packet[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa}; uint32_t len = sizeof(packet); uint32_t mtu = 1472; fragment_packet(packet, len, mtu); // assume fragments are received in order and all belong to the same packet uint32_t num_frags = 3; ip_header_t *headers[num_frags]; uint16_t ids[] = {12345, 12345, 12345}; uint16_t offsets[] = {0, 185, 370}; for (uint32_t i = 0; i < num_frags; i++) { headers[i] = malloc(IP_HEADER_LEN); memset(headers[i], 0, IP_HEADER_LEN); ip_header_t *header = headers[i]; header->ver_ihl = 0x45; header->total_len = htons(1480); header->id = htons(ids[i]); header->frag_off = htons(offsets[i] / 8); if (i == num_frags - 1) { header->frag_off |= htons(0x2000); } header->ttl = 64; header->protocol = 17; header->src_addr = 0x0100007f; header->dest_addr = 0x0100007f; } reassemble_packet(headers, num_frags); // free headers for (uint32_t i = 0; i < num_frags; i++) { free(headers[i]); } return 0; } ``` 该示例代码实现了IP分片和重组的基本功能,可以按照指定的MTU将一个IP数据包分成多个片段,并将这些片段发送到网络上;同时,也可以接收多个IP分片并将它们重组成原始数据包。这个示例代码可以作为学习IP分片和重组的入门教程,但实际应用中还需要考虑更多的细节和安全问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值