if (setsocketoption()==false) error_occurred=true;
}
其中,在创建套接字的一句socket = new socket(addressfamily.internetwork, sockettype.raw, protocoltype.ip);中有3个参数:
第二个参数设置的套接字类型就是我们使用的raw类型了,sockettype是一个枚举数据类型,raw套接字类型支持对基础传输协议的访问。通过使用 sockettype.raw,你不光可以使用传输控制协议(tcp)和用户数据报协议(udp)进行通信,也可以使用网际消息控制协议 (icmp) 和 internet 组管理协议 (igmp) 来进行通信。在发送时,您的应用程序必须提供完整的 ip 标头。所接收的数据报在返回时会保持其 ip 标头和选项不变。
第三个参数设置协议类型,socket 类使用 protocoltype 枚举数据类型向 windows socket api 通知所请求的协议。这里使用的是ip协议,所以要采用protocoltype.ip参数。
其中,设置套接字选项时必须使套接字包含ip包头,否则无法填充ipheader结构,也无法获得数据包信息。
int ret_code = socket.iocontrol(sio_rcvall, in, out);是函数中最关键的一步了,因为,在windows中我们不能用receive函数来接收raw socket上的数据,这是因为,所有的ip包都是先递交给系统核心,然后再传输到用户程序,当发送一个raws socket包的时候(比如syn),核心并不知道,也没有这个数据被发送或者连接建立的记录,因此,当远端主机回应的时候,系统核心就把这些包都全部丢掉,从而到不了应用程序上。所以,就不能简单地使用接收函数来接收这些数据报。要达到接收数据的目的,就必须采用嗅探,接收所有通过的数据包,然后进行筛选,留下符合我们需要的。可以通过设置sio_rcvall,表示接收所有网络上的数据包。接下来介绍一下iocontrol函数。msdn解释它说是设置套接字为低级别操作模式,怎么低级别操作法?其实这个函数与api中的wsaioctl函数很相似。wsaioctl函数定义如下: