IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> 用户态协议栈-TCPIP -> 正文阅读

[网络协议]用户态协议栈-TCPIP

用户态协议栈:
把协议栈当应用来写
网络协议的解析,放到应用层

本来协议栈是在系统层,用户态是调用到应用层来写的。


系统调用
listen
accept


为什么会有用户态协议栈
1、减少CPU上下切换


网卡作用:光电信号(模拟信号)转换为数字信号,AD转换,在物理层和数据链路层之前

?

内核态协议栈处理:
网卡把数据放到sk_buff,
协议栈对网卡数据进行解析,放到recvbuff中

两次拷贝:网卡copy到协议栈 协议栈copy到应用程序

将网卡内存映射到内存中间,dma方式,内存直接通道,减少网卡到协议栈拷贝,减少一次拷贝

dma没有拷贝,dma方式,cpu不需要干预,网卡数据直接到内存,零拷贝,即cpu没有干预

mmap原理:
磁盘中间的文件进行映射,蓝牙、U盘、网卡,都可以进行dma方式,把存储映射到内存中间
mmap前提:有dma总线,即支持dma方式

dma方式:数据映射完,会给cpu发送触发中断。

网卡驱动运行在哪里:运行在内核中,nic子系统,使网卡正常工作的

?

从网卡中取到一帧完整的数据:

?

实现一个协议栈:
1、netmap 开源

?

?

以太网协议头:

?

#define ETH_ALEN?? ?6

struct ethhdr {
?? ?unsigned char h_dest[ETH_ALEN];
?? ?unsigned char h_source[ETH_ALEN];
?? ?unsigned short h_proto;
};

ip头:


struct iphdr {
?? ?unsigned char version;
?? ?unsigned char tos;//实时流数据,流媒体数据方法,不一样的
?? ?unsigned short tot_len;//ip包总长度,65535byte=64k
?? ?unsigned short id;//每个ip包都有id,
?? ?unsigned short flag_off;
?? ?unsigned char ttl;//8位生存时间,每经过一个网关减一,0时网关就丢弃,返回目的不可到达。
?? ?unsigned char protocol;
?? ?unsigned short check;
?? ?unsigned int saddr;
?? ?unsigned int daddr;
};
MTU是网卡的限制,超过1500byte,ip就会进行分包。

?

UDP头:
struct udphdr {
?? ?unsigned short source;
?? ?unsigned short dest;
?? ?unsigned short len;
?? ?unsigned short check;
};
UDP没有数据包的概念

MAC地址是以太网产物,
IP地址是网络层产物
端口号是传输层产物

路由器工作在网络层的

二层交换机在局域网内,在链路层,只对mac地址进行交换

在网络层,则需要路由器,或者是三层交换机

nat 需要对传输层协议进行,

负载均衡LB:
nginx ?工作在应用层
haproxy ?tcp端口代理处理,传输层
lvs ? ?网络层
f5 ? ? 数据联络层


UDP packet:
struct udppkt {
?? ?struct ethhdr eh;
?? ?struct iphdr ip;
?? ?struct udphdr udp;
?? ?unsigned char body[0];//柔性数组,数组首地址
};
sizeof(udppkt)= 44;
柔性数组使用条件:
1、内存已分配好
2、柔性数组的长度可以计算出来

netmap 依赖库,翻墙,url以浏览器方式下载
virtio,uio

?

将网卡映射到内存中间,应用程序之间在网卡中取数据

虚拟机中将改为ens33->etho

#include <sys/poll.h>
#include <arpa/inet.h>


#define NETMAP_WITH_LIBS

#include <net/netmap_user.h>?
#pragma pack(1) ? //以一个字节对齐,sizeof(udppkt)= 42,这时就不是上面的44字节了

#define PROTO_IP?? ?0x0800
#define PROTO_ARP?? ?0x0806

#define PROTO_UDP?? ?17
#define PROTO_ICMP?? ?1
#define PROTO_IGMP?? ?2

struct udppkt {
?? ?struct ethhdr eh;
?? ?struct iphdr ip;
?? ?struct udphdr udp;
?? ?unsigned char body[0];//柔性数组,数组首地址
};

int main() {
?? ?
?? ?struct ethhdr *eh;
?? ?struct pollfd pfd = {0};
?? ?struct nm_pkthdr h;
?? ?unsigned char *stream = NULL;

?? ?struct nm_desc *nmr = nm_open("netmap:eth0", NULL, 0, NULL);//将网卡的数据映射到内存中,不会再走内核协议栈,etch0被netmap接管
?? ?if (nmr == NULL) {
?? ??? ?return -1;
?? ?}

?? ?pfd.fd = nmr->fd;
?? ?pfd.events = POLLIN;

?? ?while (1) {
?? ??? ?int ret = poll(&pfd, 1, -1);//dma方式数据映射完,会给cpu发送触发中断。知道网卡来数据了,netmap封装的数据
?? ??? ?if (ret < 0) continue;
?? ??? ?
?? ??? ?if (pfd.revents & POLLIN) {
?? ??? ??? ?stream = nm_nextpkt(nmr, &h);//操作内存,循环队列,读出下一个包,netmap封装,纯内存操作,没有所谓的阻塞和非阻塞概念
?? ??? ??? ?eh = (struct ethhdr*)stream;

?? ??? ??? ?if (ntohs(eh->h_proto) == PROTO_IP) {

?? ??? ??? ??? ?struct udppkt *udp = (struct udppkt*)stream;
?? ??? ??? ??? ?if (udp->ip.protocol == PROTO_UDP) {//ntohs()??

?? ??? ??? ??? ??? ?struct in_addr addr;
?? ??? ??? ??? ??? ?addr.s_addr = udp->ip.saddr;

?? ??? ??? ??? ??? ?int udp_length = ntohs(udp->udp.len);
?? ??? ??? ??? ??? ?printf("%s:%d:length:%d, ip_len:%d --> ", inet_ntoa(addr), udp->udp.source,?
?? ??? ??? ??? ??? ??? ?udp_length, ntohs(udp->ip.tot_len));

?? ??? ??? ??? ??? ?udp->body[udp_length-8] = '\0';
?? ??? ??? ??? ??? ?printf("udp --> %s\n", udp->body);
#if 1
?? ??? ??? ??? ??? ?struct udppkt udp_rt;
?? ??? ??? ??? ??? ?echo_udp_pkt(udp, &udp_rt);
?? ??? ??? ??? ??? ?nm_inject(nmr, &udp_rt, sizeof(struct udppkt));
#endif
#if 0
?? ??? ??? ??? ?} else if (udp->ip.protocol == PROTO_ICMP) {//ntohs()??
?? ??? ??? ??? ??? ?
?? ??? ??? ??? ??? ?struct icmppkt *icmp = (struct icmppkt*)stream;

?? ??? ??? ??? ??? ?printf("icmp ---------- --> %d, %x\n", icmp->icmp.type, icmp->icmp.check);
?? ??? ??? ??? ??? ?if (icmp->icmp.type == 0x08) {
?? ??? ??? ??? ??? ??? ?struct icmppkt icmp_rt = {0};
?? ??? ??? ??? ??? ??? ?echo_icmp_pkt(icmp, &icmp_rt);

?? ??? ??? ??? ??? ??? ?//printf("icmp check %x\n", icmp_rt.icmp.check);
?? ??? ??? ??? ??? ??? ?nm_inject(nmr, &icmp_rt, sizeof(struct icmppkt));
?? ??? ??? ??? ??? ?}
#endif?? ?
?? ??? ??? ??? ?} else if (udp->ip.protocol == PROTO_IGMP) {//ntohs()??

?? ??? ??? ??? ?} else {
?? ??? ??? ??? ??? ?printf("other ip packet");
?? ??? ??? ??? ?}
#if 0
?? ??? ??? ?} ?else if (ntohs(eh->h_proto) == PROTO_ARP) {

?? ??? ??? ??? ?struct arppkt *arp = (struct arppkt *)stream;
?? ??? ??? ??? ?struct arppkt arp_rt;

?? ??? ??? ??? ?if (arp->arp.dip == inet_addr("192.168.2.217")) {
?? ??? ??? ??? ??? ?echo_arp_pkt(arp, &arp_rt, "00:50:56:33:1c:ca");
?? ??? ??? ??? ??? ?nm_inject(nmr, &arp_rt, sizeof(struct arppkt));
?? ??? ??? ??? ?}
#endif
?? ??? ??? ?}
?? ??? ?}?
?? ?}
}

libpcap 原生socket
netmap 对socket进行了优化

read :从外存读到内存
write:

外界向网卡发送数据时,网卡将数据映射到内存中,内存中用循环队列存储,只要记得队列都在哪,

0拷贝运用场景
日志操作 fwrite,write
mmap,open文件映射到内存,日志 落盘到内存,由netmap操作内存写到文件中
效率:mmap效率比之间操作文件要快。
缺点:可能会丢数据,进程断电时,会丢几帧数据。不能保证数据完全存入到文件

ntohs 网络字节 操作2字节以上的 必须做网络字节序转换 网络字节转本地


arp,linux用netmap接管的网卡,代码中没有实现arp协议,windows arp缓存表超时删除了接管网卡的mac地址,没有学到mac地址,所以ping不通,
同时接管的网卡也没有实现icmp协议

arp:局域网内,广播,我是192.168.0.1 你的mac地址是多少,本地建立arp表,ip地址是多少,mac地址是多少

windows下 查看arp表:
arp -a

UDP优点
1、实时性强,游戏
2、不带拥塞控制,传输速度比tcp快

用户态协议栈使用场景:网关,负载均衡,网络防火墙,性能,


?

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-01-17 11:49:32  更:2022-01-17 11:50:21 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年10日历 -2024/10/5 9:29:24-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码