芯机智

 找回密码
 立即注册

扫一扫,访问微社区

搜索
热搜: 活动 交友 discuz
查看: 47|回复: 0

ioctl() fcntl() setsockopt() ioctlsocket()

[复制链接]

534

主题

624

帖子

6282

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
6282
发表于 2019-7-2 11:09:10 | 显示全部楼层 |阅读模式
int ioctl(int d, int request, ...); 后续是否有参数根据第二个参数request的需要来决定。
ioctl用于硬件设备I/O通道控制,控制命令与参数都与设备高度相关,通常也与系统高度相关。

int fcntl(int fd, int cmd, ... /* arg */ );后续是否有参数根据第二个参数cmd的需要来决定。这点两者相同。
操作控制的对象是: 文件描述符。

ioctl()是底层的系统调用(system call),所以跨平台特性不好。
而fcntl则是被封装的函数,各个OS都是支持的。
在网络socket中,他们作用大概相似。

例如都可以设置socket的是否允许非阻塞模式,不过设置方式上略有不同:
int socketfd = .....;

fcntl(sockfd, F_SETFL,fcntl(sockfd, F_GETFL, 0) |O_NONBLOCK);
ioctl(sockfd, FIONBIO,1);  1:非阻塞0:阻塞

int setsockopt(int sockfd, int level, int optname, void *optval,socklen_t *optlen);
设置套接字选项.只能操作套接字。

sockfd:    套接字
level:     协议层  SOL_SOCKET/IPPROTO_IP/IPPRO_TCP
optname:   选项名  每一个协议层都有其固定的选项名
optval:    缓冲区  set是指向将要存放的地址, get是指向目前存放信息的地址
optlen:    缓冲区大小长度

在socket层常用操作有:
SO_BROADCAST            允许发送广播数据                  int
SO_DEBUG        允许调试                int
SO_DONTROUTE      不查找路由               int
SO_ERROR        获得套接字错误             int
SO_KEEPALIVE      保持连接                int
SO_LINGER        延迟关闭连接              structlinger
SO_OOBINLINE      带外数据放入正常数据流         int
SO_RCVBUF        接收缓冲区大小             int
SO_SNDBUF        发送缓冲区大小             int
SO_RCVLOWAT       接收缓冲区下限             int
SO_SNDLOWAT       发送缓冲区下限             int
SO_RCVTIMEO       接收超时                structtimeval
SO_SNDTIMEO       发送超时                structtimeval
SO_REUSERADDR      允许重用本地地址和端口         int
SO_TYPE         获得套接字类型             int
SO_BSDCOMPAT      与BSD系统兼容              int

使用 SO_RECVBUF 和 SO_SENDBUF可以改变缺省缓冲区大小
例:
  //设置接收缓冲区大小
  intn_recvbuf = 32 * 1024;
  setsockopt(sockfd, SOL_SOCKET,SO_RECVBUF, (const char*)&n_recvbuf,sizeof(int));

  //设置发送缓冲区大小
  intn_sendbuf = 32 * 1024;
  setsockopt(sockfd, SOL_SOCKDET,SO_SENDBUF, (const char*)&n_sendbuf,sizeof(int));

使用SO_REUSERADDR:
  1.当有一个有相同本地地址和端口的socket1处于TIME_WAIT状态时,而你启动的程序的socket2要占用该地址和端口,你的程 序就要用到该选项。
  2.SO_RESUERADDR允许同一port上启动同一服务器的多个实例(多个进程),但每个实例绑定的IP地址是不能相同的。

  3.SO_RESUERADDR允许单个进程绑定相同的端口到多个socket上,但每个socket绑定的ip地址不同。

  4.SO_RESUERADDR允许完全相同的地址和端口的重复绑定,但这只用于UDP的多播,不用于TCP。
setsockopt()只是针对socket设置参数,是在连接中的参数控制,在OS层级的控制则由ioctl和fcntl控制。如果要是获取socket参数则使用getsockopt.

在终极的分析中,一切知识都是历史;在抽象的意义下,一切科学都是数学;在理性的基础上,所有的判断都是统计。——C.R. Rao
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|芯机智 ( 京ICP备18048803号 )

GMT+8, 2019-10-15 07:35 , Processed in 0.144417 second(s), 21 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表