SOCK_RAW编程
TCP(SOCK_STREAM)和UDP套接口(SOCK_DGRAM)可以满足大部分需求,但要获取底层协议内容就需要原始套接字。相比前两者,SOCK_RAW具有如下优点:
1)使用原始套接字可以读写ICMP及ICMP6,如ping程序就是使用原始套接字发送ICMP应答请求。
2)使用原始套接字可以读写特殊的IP数据包,内核不处理这些数据包的IP协议字段,而出错的诊断将依靠字段的含义。
3)利用原始套接口设置IP_HDRINCL套接口选项可以构造自己的IP头部。
创建
int sockfd=socket(AF_INET, SOCK_RAW, protocol);
AF_INET:使用IPv4协议
SOCK_RAW:原始套接字
protocol:协议名
建立原始套接口后,可以通过它向网络中写自己的IP数据包,为了防止非法用户破坏网络,规定只有超级用户才有创建原始套接口的权限。
输入
内核如何将接收到的分组发送给原始套接字,遵循如下原则:
》接收到的TCP和UDP分组绝不会传递给任何原始套接子。
》当内核处理完ICMP消息之后,绝大部分ICMP分组将传递给原始套接口。
》当内核处理完IGMP消息后,所有IGMP分组将传递给某个原始套接口。
》所有带有内核不能识别的协议字段的IP数据包都将传递给某个原始套接口,而内核只是检验IP头部中的某些字段。
如果数据包以分片形式到达,则该分组将在所有分片到达并重组后才传给该套接字。
输出
如果套接字没有使用函数connect进行链接,则可以调用函数sendto或sendmsg,他们可以指定目的IP地址。如果已经连接,可以调用write/writev或send。
如果没有设置IP_HDRINCL选项,则内核写的数据起始地址指IP头部之后的第一个字节,此时内核构造IP头部,并且内核将IP头部的协议段设为用户在调用socket()时指定的protocol参数。
如果设置IP_HDRINCL选项,则内核写的数据起始地址指向IP头部的第一个字节,用户所提供的数据的大小值必须包括头部的字节数,此时进程构造出以下两项以外的整个IP头部:IP标识字段可以设为0,要求内核设置该值,IP头部的校验由内核来计算和存储。类似TCP协议超出外出接口的分组,内核将其分片。
匹配
当内核准备好一个待传输的数据包之后,内核将对所有的进程的原始套接口进行寻找,每个匹配的套接字都将收到一个该IP数据包的复制。匹配的过程分为3个测试步骤,只有3个测试步骤都满足时,数据包才会传递给该套接字。
》在创建套接字时,如果protocol不为0,则接收到的数据包的协议字段应该与之匹配。
》如果在原始套接口上绑定一个本地IP地址,那么接收到的数据包的地址应该与之匹配。
》如果此原始套接字通过调用connect()指定一个对方IP地址,那么接收到的源IP地址应该与之相匹配。
技巧:如果一个原始套接子创建参数protocol设置为0,并且没有调用connect()和bind(),那么对于内核传递给原始套接子的每个原始数据包,该套接口都会收到一个复制数据包。
示例
网上找到一个判断网络是否连通的程序,其通过发送ICMP包来实现。
参考:
1. linux环境下C编程指南
SOCK_RAW编程的更多相关文章
- UNIX网络编程——原始套接字SOCK_RAW
实际上,我们常用的网络编程都是在应用层的报文的收发操作,也就是大多数程序员接触到的流式套接字(SOCK_STREAM)和数据包式套接字(SOCK_DGRAM).而这些数据包都是由系统提供的协议栈实现, ...
- python select网络编程详细介绍
刚看了反应堆模式的原理,特意复习了socket编程,本文主要介绍python的基本socket使用和select使用,主要用于了解socket通信过程 一.socket模块 socket - Low- ...
- Linux Socket 原始套接字编程
对于linux网络编程来说,可以简单的分为标准套接字编程和原始套接字编程,标准套接字主要就是应用层数据的传输,原始套接字则是可以获得不止是应用层的其他层不同协议的数据.与标准套接字相区别的主要是要开发 ...
- Linux Socket 网络编程
Linux下的网络编程指的是socket套接字编程,入门比较简单.在学校里学过一些皮毛,平时就是自学玩,没有见识过真正的socket编程大程序,比较遗憾.总感觉每次看的时候都有收获,但是每次看完了之后 ...
- Python(七)Socket编程、IO多路复用、SocketServer
本章内容: Socket IO多路复用(select) SocketServer 模块(ThreadingTCPServer源码剖析) Socket socket通常也称作"套接字" ...
- Socket编程实践(2) Socket API 与 简单例程
在本篇文章中,先介绍一下Socket编程的一些API,然后利用这些API实现一个客户端-服务器模型的一个简单通信例程.该例子中,服务器接收到客户端的信息后,将信息重新发送给客户端. socket()函 ...
- Socket编程实践(1) 基本概念
1. 什么是socket socket可以看成是用户进程与内核网络协议栈的编程接口.TCP/IP协议的底层部分已经被内核实现了,而应用层是用户需要实现的,这部分程序工作在用户空间.用户空间的程序需要通 ...
- Windows 网络编程
网络编程 API ,失败返回 -,错误代码 WSASYSNOTREADY 表示基础网络子系统没有准备好网络通行,WSAVERNOTSUPPORTED 表示 Socket 版本不支持,WSAEINPRO ...
- 进击的Python【第七章】:Python的高级应用(四)面向对象编程进阶
Python的高级应用(三)面向对象编程进阶 本章学习要点: 面向对象高级语法部分 静态方法.类方法.属性方法 类的特殊方法 反射 异常处理 Socket开发基础 一.面向对象高级语法部分 静态方法 ...
随机推荐
- jstl标签不起作用不管用,jstl标签直接输出表达式
jstl标签不起作用不管用,jstl标签直接输出表达式 解决办法: 在jsp页面头上 引入: <%@ page isELIgnored="false"%> 便能够解决.
- Akka概念集
(转)http://www.csdn.net/article/2014-12-17/2823174 在Akka里面,和Actor通信的唯一方式就是通过ActorRef.ActorRef代表Actor的 ...
- java nb
Java领域有非常多著名的人物.他们为Java社区编写框架.产品.工具或撰写书籍改变了Java编程的方式. 本文是<最受欢迎的8位Java牛人>的2.0版本号. PS:排名不分先后.本文的 ...
- Git学习笔记四--远程仓库
Git远程仓库 Git是分布式版本控制系统,同一个Git仓库,可以分布到不同的机器上. 怎么分布呢?最早,肯定只有一台机器有一个原始版本库,此后,别的机器可以“克隆”这个原始版本库,而且每台机器的版本 ...
- django2自动发现项目中的url
根据路飞学城luffycity.com 的crm项目修改的 1 url入口:rbac/urls.py urlpatterns = [ ... # 批量操作权限 re_path(r'^multi/per ...
- tomcat+nginx+redis集群试验
Nginx负载平衡 + Tomcat + 会话存储Redis配置要点 使用Nginx作为Tomcat的负载平衡器,Tomcat的会话Session数据存储在Redis,能够实现0当机的7x24 运 ...
- sql中判断某个字符串是否包含一个字符串
如果想从SQL Server中查询包含某个关键字的东东,怎么查询呢? 一般有两个方法: 1.用like——select * from tablename where field1 like like ...
- 解决在IE9,IE10浏览器下,程序没有任何错误,easy ui页面不加载任何数据的问题
对于web应用程序,经常用到开发人员工具,按F12,可以调试脚本,可以查看监视网络,查看各页面加载时间,非常方便,今天在调试js时,不小心打开了兼容性视图, 之后每次打打开页面时,均不显示页面post ...
- 【转】C#播放H264裸码流
原文地址:https://www.cnblogs.com/cangyue080180/p/5873351.html 要播放H264裸码流,可以分拆为以下三个工作: 1.解码H264裸码流获取YUV数据 ...
- java基础讲解01-----简单了解一下java
2017-4-12(晚) 闲来无事,静静把自己了解的java,好好回忆一次.如果能帮助别人也好.会不断补充 java有关的书籍真的很多,我也不过多的介绍了. 1.什么是java 2.java的语言特 ...