zoukankan      html  css  js  c++  java
  • 关于linux 原始套接字编程

    关于linux 网络编程最权威的书是<<unix网络编程>>,但是看这本书时有些内容你可能理解的不是很深刻,或者说只知其然而不知其所以然,那么如果你想搞懂的话那么我建议你可以看看网络协议栈的实现。

    函数原型是  int socket(int domain, int type, int protocol); 

    其中domain 中AF_INET , AF_UNIT 较为常用,分别创建inet 域套接字和unix域套接字,unix套接字与文件相关。平时80%用的套接字都是AF_INET。这里说的有点多。

    type 字段 原始套接字为SOCK_RAW

    protocol字段 其他协议已经占用的该字段不能使用, 系统保留的也不能使用。

    当接受到一份ip 数据包时,在向L4层递交的过程中会查看ip层报头中上层协议字段,如果是tcp udp icmp  则交给tcp udp  icmp的处理函数来处理.如果找不到相应的处理函数(应该说找不到相应的struct proto ),那么就把相应的数据包发给原始套接字,但是不是每一个原始套接字都接受这样的数据包,必须同使满足三个要求:(来自<<unix 网络编程>>)

    1.ip 数据包首部的上层协议字段必须好创建套接字时的第三个字段相同。

    2.创建原始套接字时使用了bind (其实主要是为了绑定ip地址),ip数据包中的目的地址必须和套接字绑定的地址相同

    3.如果发送数据是用了sendto 那么sendto中的目的地址必须套接字的地址一样。

    下面来说下原始套接字的发送和接受的数据都是从哪个地方开始的(可以参考前面linux c ping 实现一文)

    发送的时候 ip首部后的第一个字节为发送的起点。

    接收的时候 接收完整的ip数据包包括ip头部

    有人可能会问有没有办法获取tcp udp 的数据

    答案当然是有

    这时候你需要原始ip套接字。现在来谈论下原始套接字和原始ip的不同。从名字上原始套接字,原始的数据是ip的载荷(L4层),原始ip套接字原始的L2载荷(L3层),所以在发送的时候,原始套接字只需要发送完整的L4层内容。原始ip套接字发送的时候需要发送完整的L3层内容,其ip报头的大部分内容需要自己来指定。

    在接受的时候原始套接字接受完整的ip 层, 原始ip套接字接收完整L2层内容,这样你出去以太网头部,ip层头部,L4头部,那么剩下啦的就是tcp 或者 udp 的数据。

  • 相关阅读:
    平台
    重构之践
    Linux.NET
    系统分析员级下午试题II(论文)解答方法
    通用泛型存储接口的设计
    .NET平台4.0 发布网站流程及出错总结
    在IIS上发布基于Windows Azure Service Bus的WCF服务
    epoll + 多线程实现并发网络连接处理
    Linux进程地址空间之初探:一
    排序、搜索
  • 原文地址:https://www.cnblogs.com/cdwodm/p/4896275.html
Copyright © 2011-2022 走看看