原始套接字
(2012-12-20 01:16:34)
标签:
365 |
分类: IT世界任我游 |
原始套接字是一种底层技术,它工作在网络层,利用原始套接字可以完成如下:
1、设置网卡为混杂模式,嗅探当前网络流经本网卡的所有数据包
2、构造各种数据包(IP,ICMP,TCP,UDP等),并进行发送
3、进行新协议的验证
原始套接字是一种更底层的套接字技术,它与流式或者数据包套接字在功能上有很大的不同。流式/数据包套接字只能提供传输层及传输层以上的编程服务,而原始套接字可以提供上至应用层,下至链路层的编程服务。
原始套接字技术的灵活性较强,功能强大,甚至可以用它开发整个TCP协议。
一、创建
二、数据发送
在发送之前要调用setsocketopt函数进行套接字的首部设定
数据包的发送一般调用sendto函数,但在实际编程实现中要遵循以下规则:
1、若没有调用connect()函数绑定对方地址,则可以调用sendto()函数进行数据包发送
2、若调用connect()函数绑定了对方的地址,则要使用write()和send()函数执行发送操作
三、数据接收
一般使用recvfrom()函数,但在接收时注意以下细节:
1、获得传输层数据
对于传输层(如TCP或UDP)产生的IP包,Linux内核不会将它传递给原始套接字,而只是将这些数据包交给对应的应用程序。因此若想通过原始套接字获得传输层的数据,需要设置套接字属性,即在创建原始套接字时,将第三个参数htons置为ETH_P_IP
2、获得网络层数据
对于ICMP等IP层数据包,Linux内核不论是否有已经工作的应用程序处理这些报文,都会将此类数据包复制一份交与该协议类型相同的原始套接字
若想获得特定协议的网络层数据报文,可以设置原始套接字中的第三个参数为相应的协议类型
3、本地地址绑定
如果原始套接字调用bind()函数绑定了一个地址,则Linux内核只会将目的地址为绑定地址的数据包传递给原始套接字
4、远程地址绑定
如果原始套接字调用了connect()函数,则Linux内核只会将源地址与connect()函数地址相同的数据包传递给原始套接字
5、协议不识别数据包的处理
对于无法识别协议类型的数据包,Linux内核会尝试将该报文复制一份交由与其协议号相同的元式套接字处理,否则会丢弃该报文,同时向源主机发送主机不可达的ICMP报文
6、其他
若原始套接字没有调用bind()和connect()函数,则Linux内核会将所有与协议匹配的IP数据包传递给原始套接字
设置套接字属性
函数名:setsocketopt
头文件:#include <sys/socket.h>
参数表:int
sockfd
int level
int optname
const void *optval
socklen_t *optlen
返回值:int
setsockopt()函数用于任意类型、任意状态套接口的设置选项值。尽管在不同协议层上存在选项,但本函数仅定义了最高的“套接口”层次上的选项。选项影响套接口的操作,诸如加急数据是否在普通数据流中接收,广播数据是否可以从套接口发送等等。
setsockopt()支持下列选项。其中“类型”表明optval所指数据的类型。
setsockopt()不支持的BSD选项有:
Select技术
Select是一种多路复用IO输入输出模式,在Linux的输入输出编程中也可以用到Select技术,通过Select的轮询机制,发现可用、可读或可写的接口。套接字也是一种输入输出机制,所以可以使用Select这种方式进行高性能的网络程序设计。它是用在非阻塞式的网络应用程序中
server基本流程:
1、创建一个TCP服务套接字
2、设置并绑定本地地址
3、在指定端口监听
4、将服务套接字加入到检测集合
5、将客户端套接字集合中可用的套接字加入到检测集合
6、设置select函数
7、判断当前是否有可读的客户端套接字,若有则读取其中数据,并调用send()函数发送给该客户端
8、若当前有新连接,则加入到客户端套接字集合,若数量过载,则断开本次连接,并发送提示消息“”
9、清空断开的套接字,并转向4
广播技术
设计广播程序时,要进行套接字的属性设置。另外广播通信要采用UDP的方式,其具体的流程如下。
1、创建UDP套接字
2、设置套接字属性为SO_BROADCAST,即设置程序的广播属性
3、设置广播地址为 INADDR_BROADCAST,同时也要指定发送的端口
4、进行数据的收发操作
服务器端程序流程:
1、创建UDP套接字
2、设置套接字属性为SO_BROADCAST
3、设置本地地址,其中地址为INADDR_BROADCAST,端口为INADDR_ANY
4、绑定本地地址
5、设置广播地址,其中地址为INADDR_BROADCAST,端口为5050(随意指定的)
6、开始收发操作
客户端程序流程:
1、创建UDP套接字
2、设置本地地址,其中地址为INADDR_ANY,端口为5050(服务端指定的)
3、设置套接字属性为地址可重用,即setsocketopt为SO_REUSEADDR
4、绑定本地地址
5、开始收发操作
组播技术
服务器端通过指定一个多播地址,创建一个多播组。
客户端通过指定的多播地址加入多播组