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编程指南

2. linux下判断网络是否连接

SOCK_RAW编程的更多相关文章

  1. UNIX网络编程——原始套接字SOCK_RAW

    实际上,我们常用的网络编程都是在应用层的报文的收发操作,也就是大多数程序员接触到的流式套接字(SOCK_STREAM)和数据包式套接字(SOCK_DGRAM).而这些数据包都是由系统提供的协议栈实现, ...

  2. python select网络编程详细介绍

    刚看了反应堆模式的原理,特意复习了socket编程,本文主要介绍python的基本socket使用和select使用,主要用于了解socket通信过程 一.socket模块 socket - Low- ...

  3. Linux Socket 原始套接字编程

    对于linux网络编程来说,可以简单的分为标准套接字编程和原始套接字编程,标准套接字主要就是应用层数据的传输,原始套接字则是可以获得不止是应用层的其他层不同协议的数据.与标准套接字相区别的主要是要开发 ...

  4. Linux Socket 网络编程

    Linux下的网络编程指的是socket套接字编程,入门比较简单.在学校里学过一些皮毛,平时就是自学玩,没有见识过真正的socket编程大程序,比较遗憾.总感觉每次看的时候都有收获,但是每次看完了之后 ...

  5. Python(七)Socket编程、IO多路复用、SocketServer

    本章内容: Socket IO多路复用(select) SocketServer 模块(ThreadingTCPServer源码剖析) Socket socket通常也称作"套接字" ...

  6. Socket编程实践(2) Socket API 与 简单例程

    在本篇文章中,先介绍一下Socket编程的一些API,然后利用这些API实现一个客户端-服务器模型的一个简单通信例程.该例子中,服务器接收到客户端的信息后,将信息重新发送给客户端. socket()函 ...

  7. Socket编程实践(1) 基本概念

    1. 什么是socket socket可以看成是用户进程与内核网络协议栈的编程接口.TCP/IP协议的底层部分已经被内核实现了,而应用层是用户需要实现的,这部分程序工作在用户空间.用户空间的程序需要通 ...

  8. Windows 网络编程

    网络编程 API ,失败返回 -,错误代码 WSASYSNOTREADY 表示基础网络子系统没有准备好网络通行,WSAVERNOTSUPPORTED 表示 Socket 版本不支持,WSAEINPRO ...

  9. 进击的Python【第七章】:Python的高级应用(四)面向对象编程进阶

    Python的高级应用(三)面向对象编程进阶 本章学习要点: 面向对象高级语法部分 静态方法.类方法.属性方法 类的特殊方法 反射 异常处理 Socket开发基础 一.面向对象高级语法部分 静态方法 ...

随机推荐

  1. SQL Server 2005/2008备份数据库时提示“无法打开备份设备”

    错误描述: 今天备份sqlserver 2008数据库时候,想要将备份文件放在f盘的根目录下,结果提示如下信息:备份对于服务器“服务器名”失败.(Microsoft.SqlServer.Smo)其他信 ...

  2. 记一次vue2项目部署nginx静态文件404解决过程

    github上下的一个vue2的项目,运行可以的,webpack打包后,nginx请求报错: 发现路径很奇怪啊,所以果断来到build.js文件中看看是不是哪里不对. 已经一番引用查找: 发现在这里配 ...

  3. 关于js加密解密

    有的时候有些网站的js用简单的eval混淆加密了.解密其实很简单的 解密JS的eval加密码的方式例如这段: 很多朋友以为这段代码是“加密”的,其实这也谈不上是加密,只能算是一种编码(Encode)或 ...

  4. JBoss 系列十七:使用JGroups构建块MessageDispatcher 构建群组通信应用

    内容概要 本部分说明JGroups构建块接口MessageDispatcher,具体提供一个简单示例来说明如何使用JGroups构建块MessageDispatcher 构建群组通信应用 示例描述 构 ...

  5. Firefly 其他博客

    http://www.cnblogs.com/9miaoshetuan/tag/Firefly/ http://www.cnblogs.com/9miaoshetuan/p/3853124.html ...

  6. Unity3D研究院之DontDestroyOnLoad的坑

    http://www.xuanyusong.com/archives/2938 Unity中的一个方法DontDestroyOnLoad可以让某些游戏对象在切换场景的时候不是施放,听起来是一个非常好的 ...

  7. Openerp开发进销存系统完毕总结

      转自:http://blog.csdn.net/heartrude/article/details/9142463 安装Openoffice 在openoffice中安装openerp repor ...

  8. 【Python3 爬虫】17_爬取天气信息

    需求说明 到网站http://lishi.tianqi.com/kunming/201802.html可以看到昆明2018年2月份的天气信息,然后将数据存储到数据库. 实现代码 #-*-coding: ...

  9. Cacti监控MySQL实现过程中碰到的问题解汇总

    前言:cacti监控mysql服务器的大概50张graphs都弄出来了,也出图了,当中遇到一些问题,印象比較深刻的记录例如以下: (一):加入io监控 点击Create Graphs for this ...

  10. 分享一下自己ios开发笔记

    // ********************** 推断数组元素是否为空 ********************** NSString *element = [array objectAtIndex ...