IP 是TCP/IP协议栈中重要的层次, TCP UDP ICMP IGMP都是依赖IP层进行传输的。首先它是一种不可靠,无连接的协议。不可靠:它不保证IP包能正确到达目的地,无连接:表示IP并不会维护后续数据包的信息,每个数据包的传输都是独立的。数据包的可靠性需要依赖传输层协议来保证如TCP协议,也就是说当一个比特流从网络接口发送向网络之后,所经过的每个路由器会解析数据包的网络层的信息,再通过路由算法选一条路发送出去,所有包不一定会选择同一条道路。网络层负责点到点的通信,尽量将数据包发送到目的主机,若不能到达目的主机IP有一个简单的错误处理算法:丢弃该数据报,然后发送 ICMP消息报给信源端。

IP首部信息:

如果没有IP选项的话IP首部应该是20字节。用wireshark抓包分析一下

4位版本号: 0100 表示IPv4 若是IPv6的话应该是0110
4位首部长度:0101 表示20个字节,这是因为首部长度指的是首部占 32 bit字的数目,包括任何选项。由于它是一个 4比特字段,因此首部最长为6 0个字节。也就是说这四个比特一个比特表示4个字节。
8位服务类型:服务类型(TO S)字段包括一个3 bit的优先权子字段(现在已被忽略) ,4 bit的TOS子字段和1 bit未用位但必须置0。4 bit的TOS分别代表:最小时延、最大吞吐量、最高可靠性和最小费用。普通数据包里一般都为0x00. 对于不同应用可能会选择不同的TOS。如TFTP telnet等。
16位总长度:表明IP数据包的总长度 最大65535个字节, 但考虑到链路层的MTU 一般这个值要小于1500。拿这个总长度减去IP首部长度就是TCP UDP 等数据包长度。
接下来的4个字节就是表示IP分片的记录信息:

前两个字节表示:那个数据包的分片,标识同一个数据报分片
3位标志表示:是否有更多分片,最后一个IP分片里都为0表示没有分片了
13位片偏移:分片在原始数据的偏移量。
另外在分片过程中传输层信息只会出现在第一个分片中。IP层不知道也不需要保证在每个分片中都有传输层首部。到达目的主机时IP层会把这些IP片组合起来。若有片丢失的话,就会重传整个数据报。组合起来的数据报再交给传输层解析。

最后的几个字节包含目的IP源IP和IP选项(若有)。
下面做一个UDP传输实例看一下IP层分片。

#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#define PORT 4444
int main(int argc, char *argv[])
{
if(argc != 2)
{
printf("./udpclient IP\n");
return 1;
}
int fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0)
return 1;
struct sockaddr_in server;
server.sin_family = AF_INET;
server.sin_port = htons(PORT);
if (!inet_pton(AF_INET, argv[1], (void *)&server.sin_addr))
{
printf("IP error\n");
return -1;
}
char buff1[65535] = "sdfsdfsdf";
char buff2[2048] = {0};
socklen_t size = sizeof(struct sockaddr);
while(1)
{
sendto(fd, buff1, 65535, 0, (const struct sockaddr *)&server, size);
sleep(5);
recvfrom(fd, buff2, 2048, 0, NULL, NULL);
printf("recv : %s\n", buff2);
} }

服务器端

#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#define PORT 4444
int main()
{
int fd = socket(AF_INET, SOCK_DGRAM, 0);
if(fd < 0)
return -1;
struct sockaddr_in server, client;
server.sin_family = AF_INET;
server.sin_port = htons(PORT);
server.sin_addr.s_addr = htonl(INADDR_ANY);
bind(fd, (const struct sockaddr *)&server, sizeof(struct sockaddr));
socklen_t len = sizeof(struct sockaddr);
char buff[2048] = {0};
while(1)
{
recvfrom(fd, buff, 2048, 0,(struct sockaddr *)&client, &len);
printf("%s send msg: %s \n", inet_ntoa(client.sin_addr), buff);
sendto(fd, "OK", 2, 0, (const struct sockaddr *)&client, len);
}
}

抓包结果可以看到:

~# tcpdump -i eth0 -v udp and host 192.168.1.3
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
18:21:40.171370 IP (tos 0x0, ttl 64, id 39920, offset 0, flags [+], proto UDP (17), length 1500)
192.168.1.3.39170 > 192.168.1.4.4444: UDP, length 2048
18:21:40.171385 IP (tos 0x0, ttl 64, id 39920, offset 1480, flags [none], proto UDP (17), length 596)

这里可以看到被分成的两个组,2096 - 2048 = 48字节: 多出的48个字节包含俩个IP头40 + 一个UDP头8 字节??

TCP/IP协议栈 --- 网络层(IP 首部 和分片)的更多相关文章

  1. 浅谈TCP IP协议栈(四)IP协议解析

    通过之前的网络层基础知识,IP地址以及路由器的简介,大家应该对于TCP/IP有一个大致的了解,在脑海里应该对于网络的几个基础概念有个大概的了解,简单点说整个协议栈就是在做一件事,规定网络报文(网络传输 ...

  2. 浅谈TCP IP协议栈(二)IP地址

    上一节大致了解TCP/IP协议栈是个啥东西,依旧是雾里看花的状态,有很多时候学一门新知识时,开头总是很急躁,无从下手,刚学会一点儿,却发现连点皮毛都不算,成就感太低,所以任何时候学习最重要的是要在合适 ...

  3. 浅谈TCP IP协议栈(三)路由器简介

    读完这个系列的第一篇浅谈TCP/IP协议栈(一)入门知识和第二篇浅谈TCP/IP协议栈(二)IP地址,在第一篇中,可能我对协议栈中这个栈的解释有问题,栈在数据结构中是一种先进后出的常见结构,而在整个T ...

  4. 几个主流TCP/IP协议栈介绍

    我们知道TCP IP协议栈内包括了诸多协议.那么对于这当中的协议的功能以及作用,我们来具体了解一下吧.现在让我们做一个盘点,帮助大家总结一下,还望对大家能够有所帮助. 1.BSD TCP IP协议栈 ...

  5. 结合Wireshark捕获分组深入理解TCP/IP协议之IP协议

    摘要:     本文简单介绍了网络层理论知识,详细讲解了IP数据报各个字段,并从Wireshark俘获分组中选取IP数据报进行分析,也阐述了分组和分片的区别.   一.IPv4数据报     网络层是 ...

  6. 【转】TCP/IP协议栈及OSI参考模型详解

    OSI参考模型 OSI RM:开放系统互连参考模型(open systeminterconnection reference model) OSI参考模型具有以下优点: 简化了相关的网络操作: 提供设 ...

  7. TCP/IP协议栈及OSI参考模型详解

    OSI参考模型 OSI RM:开放系统互连参考模型(open systeminterconnection reference model) OSI参考模型具有以下优点: 简化了相关的网络操作: 提供设 ...

  8. TCP/IP协议栈模型

    OSI七层模型介绍: 下面4层(物理层.数据链路层.网络层和传输层)主要提供数据传输和交换功能,即以节点到节点之间的通信为主:第4层作为上下两部分的桥梁,是整个网络体系结构中最关键的部分:而上3层(会 ...

  9. linux OSI七层模型、TCP/IP协议栈及每层结构大揭秘

    学习Linux,就算是像小编我这样的小萌新,也知道OSI模型.什么?!你不知道!!! 好吧,这篇秘籍拿走,不谢~~~ 一.两个协议 (1)OSI 协议模型(7层)国际协议    PDU:协议数据单元对 ...

随机推荐

  1. Spring 笔记总结

    1.Spring框架的核心是提供一个容器(BeanFactory 或 ApplicationContext),提供以下功能: 1)创建和销毁组件对象,类似"工厂类" 2)采用不同的 ...

  2. Android 自定义View实现QQ运动积分抽奖转盘

    因为偶尔关注QQ运动, 看到QQ运动的积分抽奖界面比较有意思,所以就尝试用自定义View实现了下,原本想通过开发者选项查看下界面的一些信息,后来发现积分抽奖界面是在WebView中展示的,应该是在H5 ...

  3. yii2之GridView小部件

    GridView小部件用于展示多条数据的列表.GridView小部件的使用需要数据提供器即yii\data\ActiveDataProvider的实例作为参数,所以 第一步就是要在控制器方法中创建这个 ...

  4. Nginx监控-Nginx+Telegraf+Influxb+Grafana

    搭建了Nginx集群后,需要继续深入研究的就是日常Nginx监控. Nginx如何监控?相信百度就可以找到:nginx-status 通过Nginx-status,实时获取到Nginx监控数据后,如何 ...

  5. javascript 之变量对象-09

    变量对象 变量对象:每个执行环境(执行上下文)都有一个对应的变量对象(variable object),环境中(执行上下文中)定义的所有变量.函数都保存在这个对象中. 在上篇中说到,当执行流执行一个函 ...

  6. NoSQL:linux操作memcached

    缓存数据库 一 NoSQL简介 NoSQL(NoSQL = Not Only SQL ),意即"不仅仅是SQL",泛指非关系型的数据库,随着互联网web2.0网站的兴起,传统的关系 ...

  7. 用大白话扯扯那"神奇"的面向对象编程思维(一)

    前言: 每当提到面向对象的时候,初学者肯定都是一脸懵逼的状态,到底什么是面向对象?会用面向对象后有什么牛逼之处吗?不会用是不是就会死掉?答案肯定不会死掉,我们可以来简单的举一 个栗子 1.当你想到熊猫 ...

  8. 一:配置使用阿里云Maven库

    鉴于国内的网络环境,从默认 Maven 库下载 jar 包是非常的痛苦. 速度慢就不说了,还经常是下不下来,然后一运行就是各种 ClassNotFoundException,然后你得找到残留文件删掉重 ...

  9. java.io.File类操作

    一.java.io.File类 String path="E:/222/aaa";//路径 String path1="aaa.txt"; File file= ...

  10. hibernate flushMode 错误

    1 十一月 15, 2017 10:13:36 上午 org.apache.struts2.dispatcher.Dispatcher error 2 严重: Exception occurred d ...