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. ray tracing/shadow,reflection, caustic

    看了一下午终于明白raytracing的算法了 不知道这次能记住多久 ssr我又完全不记得了 按照Henrik所说 理解raytracing的核心在于,它是从Eye到light反着走的 需要一个前序的 ...

  2. php 中 拓展 xdebug的完全理解

    question: Xdebug unable to connect to client, where do I start debugging the debugger? I'm setting u ...

  3. js 实现存储Map 结构的数据

    <script type="text/javascript"> function Map() { var struct = function(key, value) { ...

  4. [Functional Programming Moand] Update The State Of A State Monad (put)

    Stateful computations require the ability for their state to change overtime. We take a look on one ...

  5. xUtils怎样通过注解对FindViewById进行封装

    之前讲到了介绍了一下xUtils的基本用法,今天我们就来具体介绍一下关于xUtils中的ViewUtils模块. 在ViewUtils模块中我们首先看到的是它採用了一种注解的方式进行声明,那么我们首先 ...

  6. Odoo环境下Ubuntu服务器性能优化--参数调整

    公司在使用Odoo进行内部信息化管理,随着业务增长,服务器性能问题变成了瓶颈,为了解决这些问题,最近的工作重点将移到性能调整上来,同时也会在此记录整个处理过程,以便日后回顾. 1.根据相关资料建议,在 ...

  7. [LeetCode] Add Two Numbers(stored in List)

    首先,演示一个错误的reverList class Solution { public: ListNode* reverse(ListNode* root) { if(NULL == root) re ...

  8. struts2 Action向JSP传值方式

    1.通过属性getXXX()和setXXX()方式 Action类 public class Test { private String name; public String getName() { ...

  9. struts action不在是一个单例类

    在servlet中,servlet类是一个单例,在servlet中的成员变量,将会被所有请求共享,同时也有可能存在线程安全问题,如有一个成员变量num,每次方法后市的num自增 package act ...

  10. 准备你的Adempiere开发环境(1)- 编译

    1. 安装JDK 1.6. 2. 安装Eclipse IDE for Java EE Developers. 3. 导入adempire-360lts: 4. 关闭adempiere-360lts的B ...