Q:你好!

看过了你在csdn上发表的《用C#下的Raw Socket编程实现网络封包监视》,觉得很感兴趣,而且对我的帮助很大。不过在调试的过程中遇到一些问题,特此向你请教一下。谢谢!

首先

socket.SetSocketOption(SocketOptionLevel.IP,
SocketOptionName.HeaderIncluded, 1);

byte []IN = new byte[4]{1, 0, 0, 0};

byte []OUT = new byte[4];

//低级别操作模式,接受所有的数据包,这一步是关键必须把socket设成raw和IPLevel才可用SIO_RCVALL

int ret_code = socket.IOControl(SIO_RCVALL, IN, OUT);

ret_code = OUT[0] + OUT[1] + OUT[2] + OUT[3];//把4个8位字节合成一个32位整数

if(ret_code != 0) ret_value = false;

应改是用来设置socket的工作方式的,我想知道的是你所是值得常量SIO_RCVALL = 0x98000001是如何得到的(我是指后面的十六进制数十怎么得到的),有没有相关的文档推荐一下。我看过一些,不过没有眉目。这些数字应该是什么所谓的操作控制码,但我找不到更详细的资料,希望能指点一下。另外,在第二行中那个IN数组为什么要那么设置,这点我还不太明白。

第二

e.HeaderLength=(uint)(head->ip_verlen & 0x0F) << 2;

在这句话中,你是想要得到数据包的IP头长,从IP的结构来看,似乎是不应该移位(即左移两位)的,因为屏蔽掉前前四位之后,所剩的四位正好为头长,不知这个地方是否有问题。

第三

这段代码是由原始套接字作封包监视,但不知能否实现数据包的拦截。因为如果可以的话就可以实现放火墙的功能了。

不好意思!

第一次给你发信就问了这么一大堆,耽误了你的时间!

再次表示感谢!

等待你的回信:)

A:

第一.
在winsock2.h中定义了以下宏:
#define IOC_VOID 0x20000000 /* no parameters */
#define IOC_OUT 0x40000000 /* copy out parameters */
#define IOC_IN 0x80000000 /* copy in parameters */

#define IOC_UNIX 0x00000000
#define IOC_WS2 0x08000000
#define IOC_PROTOCOL 0x10000000
#define IOC_VENDOR 0x18000000

#define _WSAIO(x,y) (IOC_VOID|(x)|(y))
#define _WSAIOR(x,y) (IOC_OUT|(x)|(y))
#define _WSAIOW(x,y) (IOC_IN|(x)|(y))
#define _WSAIORW(x,y) (IOC_INOUT|(x)|(y))

里面没有SIO_RCVALL的定义,但是你可以查看msdn中的ms-help://MS.MSDNQTR.2003FEB.2052/winsock/winsock/wsaioctl_2.htm看WSAIoctl函数中的SIO_RCVALL 的说明,你可以知道它是这样定义的:
#define SIO_RCVALL _WSAIOW(IOC_VENDOR,1)
即:
0x80000000|0x18000000|0x00000001
其中IOC_VENDOR 实际上是IOC_WS2|IOC_PROTOCOL ,因为要receive all IP packets on the network on win32 platform.

至于用四字节数组来接收数据流,是因为网络数据流串行的在网线传输,需要接收到32位(二进制)后才能对该串行流进行解析,这是一种串行通信协议,当接收到32位后,网卡会把这32位(二进制)传给一个四字节数组。因为要和IOControl的返回值保持一致,返回的是32位的int32,所以要把out〔〕数组整合成int。至于byte []IN = new byte[4]{1, 0, 0, 0};这样定义是,因为这样整合成的整形数是(十六进制) 00 00 00 01 ,即1,输入32位数的值为一,是因为要把socket设置成非阻塞状态(which is nonzero if nonblocking mode is to be enabled and zero if it is to be disabled. )。而out得到的是一次接收操作中得到的字节数 (returns the total amount of data that can be read in a single receive operation; )。

第二:

数据包包头长的值为4位二进制,值域0-15,如果不移位的话包头长度不会超过15字节,怎么会?正如上面所说。每32位二进制是一个网络串行通信的数据单元,描述包头长的四位记录的是数据单元数,不是字节数,所以要乘与四(32bit数据单元长度/8bit字节长度),即左移二位。

第三:

基于.net的raw socket是基于winsock2来实现的,它实现在七层模型的应用层,而应用层的封包拦截向来很弱,一般在应用层实现可用spi(服务提供者),其实这需要系统调用。我试过,在.net下效果不是太好,数据包要么全部都拦住了,要么全部放行,系统反应很慢,稳定性很弱,呵呵,这是.net的隐痛。一种比较流行的做法是写网络层的ndis驱动程序,ndis hook driver和ndis中间层驱动都可以,其中ndis中间层驱动功能强大,不光可以进行封包拦截,还可以实现对网络数据流的加密,强烈建议使用!

至于在.net下做防火墙,可用managed C++做来DeviceIoControl,可以查看我的文章:
http://www.csdn.net/develop/read_article.asp?id=21480

获得RawSocket的C#源代码请访问:http://www.mscenter.edu.cn/blog/seafrog/archive/2005/05/30/2866.html

原文章地址:http://javasogo.iteye.com/blog/1062254

【转载!】关于C#的RawSocket编程的问题的更多相关文章

  1. [转载]Web前端开发工程师编程能力飞升之路

    [背景] 如果你是刚进入web前端研发领域,想试试这潭水有多深,看这篇文章吧:如果你是做了两三年web产品前端研发,迷茫找不着提高之路,看这篇文章吧:如果你是四五年的前端开发高手,没有难题能难得住你的 ...

  2. 转载--提高C++性能的编程技术

    读书笔记:提高C++性能的编程技术   第1章 跟踪范例 1.1 关注点 本章引入的实际问题为:定义一个简单的Trace类,将当前函数名输出到日志文件中.Trace对象会带来一定的开销,因此在默认情况 ...

  3. [转载]:Delphi xe7并行编程快速入门

    现在多数设备.计算机都有多个CPU单元,即使是手机也是多核的.但要在开发中使用多核的优势,却需要一些技巧,花费时间编写额外的代码.好了,现在可以使用Delphi做并行编程了. 在Delphi.C++ ...

  4. [转载] 读《UNIX网络编程 卷1:套接字联网API》

    原文: http://cstdlib.com/tech/2014/10/09/read-unix-network-programming-1/ 文章写的很清楚, 适合初学者 最近看了<UNIX网 ...

  5. 【转载】学习C++和编程的几个要点

    1.把C++当成一门新的语言学习(和C没啥关系!真的.):2.看<ThinkingIn C++>,不要看<C++变成死相>:3.看<The C++ Programming ...

  6. [转载] PHP开发必看 编程十大好习惯

    适当抽象 但是在抽象的时候,要避免不合理的抽象,有时也可能造成过渡设计,现在只需要一种螺丝刀,但你却把更多类型的螺丝刀都做出来了(而且还是瑞士军刀的样子..): 一致性 团队开发中,可能每个人的编程风 ...

  7. (转载)《C#高级编程》读书笔记

    C#类型的取值范围 名称 CTS类型 说明 范围 sbyte System.SByte 8位有符号的整数 -128~127(−27−27~27−127−1) short System.Int16 16 ...

  8. (转载)android开发常见编程错误总结

    首页 › 安卓开发 › android开发 android开发常见编程错误总结 泡在网上的日子 / 文 发表于2013-09-07 13:07  第771次阅读 android,异常 0 编辑推荐:稀 ...

  9. 【转载】《Unix网络编程》思维导图

    参考这篇文章,很不错: http://www.cnblogs.com/qiaoconglovelife/p/5734768.html

随机推荐

  1. (转)WebApi自动生成在线文档WebApiTestClient

    原文链接:http://www.cnblogs.com/landeanfen/p/5210356.html 前言:这两天在整WebApi的服务,由于调用方是Android客户端,Android开发人员 ...

  2. Arch xfce4 安装解压缩软件

    >>>安装方法 pacman -S thunar-archive-plugin xarchiver zip unzip p7zip arj lzop cpio unrar >& ...

  3. mysql创建远程用户

    grant all privileges on *.* to myuser@"%" identified by 'password'; 用root用户登陆,然后: grant al ...

  4. qt+2012+qtcreator 配置

    这个配置搞了我好久,终于搞定了,网上一大堆,总是看不懂,后来自己摸索出来的. 先贴图: 如上图:有两种配置方案: 第一:用vs2012做开发编辑.只要下载和对应插件即可,安装路径不要有空格.安装好之后 ...

  5. 【考试】简单的sql语句

    )显示正好为5个字符的员工的姓名 HR@ORA11GR2>select last_name,first_name from employees ; )显示不带有"R"的员工的 ...

  6. gem5 运行x86全系统仿真

    使用gem5可以启动Linux内核,称为全系统模拟,启动之后,可以通过telent连接,进行访问,但四telent有时不稳定,gem5推荐使用m5term进行连接访问,整个步骤如下: (1)打开终端, ...

  7. oracle限制用户连接数

    查看是否启用限制配置 SQL> show parameter resource_limit; 或者 select * from v$parameterwhere name = 'resource ...

  8. shell学习笔记(1):利用IFS打印用户和默认shell

    参考资料为:linux shell脚本攻略 作者sarath Lakshman 人民邮电出版社 shell:读取文件的每一行内容并输出 的写法1 目的:读取passwd文件,获得用户名和其默认的she ...

  9. 使用Servlet处理请求<http://blog.sina.com.cn/s/blog_5d3fb3cc0100ep9q.html>

    一.GET和POST的区别 1.GET提交的是文本内容,规定其数据长度不超过255个字符.在GET方式提交的URL中会显示出提交的查询数据而却提交数据的缓存会在浏览器的URL历史状态中,这样我们往往在 ...

  10. JS产生四位随机数的方法

    <script>var charactors="1234567890"; var value='',i; for(j=1;j<=4;j++){ i = parse ...