ioctl在socket中的一些用法及示例
函数 : ioctl(int fd, int request, void * arg)
定义 :
功能 : 控制I/O设备, 提供了一种获得设备信息和向设备发送控制参数的手段.
参数 : int fd 文件句柄. 用于socket时, 是socket套接字.
int request 函数定义的所有操作. 关于socket的操作, 定义在文件中.
void *arg 指针的类型依赖于request参数.
以下表格从网上收集了request - arg指针类型的对应关系
类别 | Request | 说明 | 数据类型 |
套 | SIOCATMARK | 是否位于带外标记 | int |
文 | FIONBIN | 设置/ 清除非阻塞I/O 标志 | int |
接 | SIOCGIFCONF | 获取所有接口的清单 | struct ifconf |
ARP | SIOCSARP | 创建/ 修改ARP 表项 | struct arpreq |
路 | SIOCADDRT | 增加路径 | struct rtentry |
流 | I_xxx |
|
|
socket最常用到的结构体: struct ifreq 定义在.(包括struct ifconf/ifr_flags等的定义)
在某C/S结构程序测试时发现一个问题
当无线网络拥塞的时候,无线层丢包很严重,TCP socket可能需要若干秒(worst case n>5)才能发出去。
发送方调用write(fd)将报文发送的时候实际上只是写入了内核的write buffer。接收方什么时候能收到报文是个未知数。
在某些需要同步状态机的地方,发送方最好能够确认接收方收到报文后再进行下一步动作
linux提供了ioctl(fd, SIOCOUTQ, &count)方法来查询一个tcp socket的write buffer是否清空。发送方一般可以用这个方法来判断对端是否收到报文。
调试程序的时候遇到了一个奇怪的问题。
CLIENT端实际上已经收到了SERVER发送的报文,开始进行下一步动作。 但是SERVER端的out queue始终显示没有发送完毕。
经过Debug后发现,实际上是client端收到报文后发送给server的TCP ACK在空口中丢失。尽管client端已经接收完毕数据,但是由于server端没有收到对应的ack,导致server端一直认为发送端没有收到数据。
所以发送方可以通过SIOCOUTQ来辅助判断tcp socket的状态。但是最好还是不要用SIOCOUTQ来绑定程序逻辑。不然容易造成死锁。