setsockopt和getsockopt函数解析
2016-04-11 21:59
543 查看
setsockopt和getsockopt函数解析:
头文件:#include <sys/types.h> #include <sys/socket.h> 函数原型: int setsockopt(int sockfd, int level, int optname, const void* optival, socklen_t optlen); 功能:用于任意类型、任意状态套接口的设置选项值. 参数: sockfd:标识一个套接口的描述字; level:选项定义的层次;支持SOL_SOCKET、IPPROTO_TCP、IPPROTO_IP和IPPROTO_IPV6; optname:需设置的选项; optval:指针,指向存放选项待设置的新值的缓冲区; optlen:optval缓冲区长度; 返回值:若无错误发生,setsockopt()返回0。否则的话,返回SOCKET_ERROR(-1)错误,应用程序可通过WSAGetLastError()获取相应错误代码。 函数原型: int getsockopt(int sockfd, int level, int optname, void* optval, socklen_t* optlen); 功能:用于获取任意类型、任意状态套接口的选项当前值,并将结果存入optval. 参数: sockfd:标识一个套接口的描述字; level:选项定义的层次;支持SOL_SOCKET、IPPROTO_TCP; optname:需获取的套接口选项; optval:指针,指向存放所获得选项值的缓冲区; optlen:指针,指向optval缓冲区的长度值; 返回值:若无错误发生,getsockopt()返回0。否则的话,返回SOCKET_ERROR(-1)错误,应用程序可通过WSAGetLastError()获取相应错误代码。 当level为SOL_SOCKET时,比较常用到的设置选项如下: 1.SO_RCVBUF和SO_SNDBUF:用于设置/读取发送缓冲区和接收缓冲区大小,选项值类型:int,指定新的缓冲区大小,对setsockopt和getsockopt有效; 说明:设置缓冲区大小只能在TCP连接建立之前进行,TCP将接收缓冲区大小用于流量控制,UDP不提供流量控制,UDP没有实际的发送缓冲区,设置发送缓冲区的大小将改变能发送的最大UDP数据报的大小,使用如下: int rcv_buf_size = 32 * 1024,snd_buf_size = 32 * 1024; setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &rcv_buf_size, sizeof(int)); setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &SND_buf_size, sizeof(int)); 2.SO_REUSEADDR: 用于复用socket地址(端口号),选项值类型:int,0—不能复用,1—可以服用,默认值为0,对setsockopt和getsockopt有效; 复用地址一般用于下列情况: a. 快速启动服务器:服务器在有客户端连接时终止,然后立即重启,由于TIME_WAIT状态的存在,会导致原来的socket依然存在,bind操作将失败,如果指定了SO_REUSEADDR选项可以避免这个问题; b. 启动一个服务程序的多个实例:当使用IP别名的时候,可以将若干个服务程序使用不同IP绑定到同一端口上; c. 多个socket绑定同一端口:用于UDP程序在有多个网络接口时,为了区分数据报来自哪一个网络接口而使用; 实例代码: int opt=1; setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(int)); 3. SO_KEEPALIVE: 用于TCPsocket检测/保持网络连接,这个选项被设置后,2小时以内双方没有数据交互,将发送一个探测数据段到对方,此时可能出现以下情况: a. 得到对方正确响应,继续等待下一次2小时超时; b. 收到RST数据段,返回错误ECONNRESET; c. 对方无响应,多次发送探测数据段直到超市返回错误ETIMEOUT; d. 选项值类型:int,0—不能发送;1—可以发送,默认值为0;对setsockopt和getsockopt有效; int opt=1; setsockopt(sockfd,SOL_SOCKET,SO_KEEPALIVE,&opt,sizeof(int)); 4. SO_LINGER: 用于设定close函数的操作方式. 选项值类型: struct linger{ int l_onoff; //选项是否有效 int l_linger; //关闭socket的延迟时间 }; 可能的情况: l_onoff=0,此时l_linger被忽略,close按默认方式工作; l_onoff非0,l_linger=0,close函数放弃连接向对方发送RST数据段,然后立即关闭socket,释放socket资源,这种情况socket不会进入TIME_WAIT状态,可能会导致以下的问题: a. 数据丢失(TCP协议丢弃未发送的数据); b. 连接非正常关闭(调用close的一方发送RST数据段,而不是FIN数据段,导致另一方认为发生错误,非正常关闭连接); c. 数据混乱(连接双方都不进入TIME_WAIT状态,因此在上次连接的数据没有从网络上消除之前,新的相同连接(IP和端口相同)可以建立,有可能会收到上次连接的数据,导致数据混乱). l_onoff和l_linger都非0,close函数阻塞,在延迟指定的时间后关闭连接,根据数据是否在延时期间内得到确认正常返回或返回错误EWOULDBLOCK; 对setsockopt和getsockopt有效; close函数只能保证数据被TCP协议正确接收,不能保证被应用程序正确接收,为了保证数据被对方应用程序接收,采用shutdown关闭写通道,继续读操作直到read函数返回0,调用close关闭连接。或者采用应用程序确认的方法实现; 实例代码: struct linger linger_opt; linger_opt.l_onoff=1; linger_opt.l_linger=1000; setsockopt(sockfd,SOL_SOCKET,SO_LINGER,&linger_opt,sizeof(linger_opt)); 当level为IPPROTO_TCP时,比较常用到的设置选项如下: 1.TCP_MAXSEG:获取和设置一个TCP连接的最大数据段的大小; 2.TCP_NODELAY:用于禁止TCP协议的Nagle算法,使小数据包(小于最大数据段大小)立即发送,会降低TCP协议的效率
相关文章推荐
- [Linux]实例浅析epoll的水平触发和边缘触发,以及边缘触发为什么要使用非阻塞IO
- LINUX内核分析第八周学习总结——进程的切换和系统的一般执行过程
- Linux内核分析——第八周学习笔记
- Hadoop Mapreduce分区、分组、二次排序过程详解
- linux grep命令
- Nginx探索二
- Linux 下用vfork()创建进程,子进程用return和exit返回的区别
- 在dos命令行输入adb shell命令时出现错误的解决方案
- 斐讯k1刷入Breed以及openwrt的教程
- Linux学习笔记13
- 《Linux内核设计与实现》第四章读书笔记
- 使用screen的时候出现了如下错误: Cannot open your terminal '/dev/pts/0' - please check.
- shell 之 进程前后台切换
- Linux 设备和模块的分类
- Linux find命令的之我的使用
- tomcat(5)servlet容器(lastest version)
- Hadoop 2.6.0集群的安装
- 利用Powershell每天自动设置提取Win10的windows聚焦图片(Spotlight)作为桌面壁纸的方法
- linux平台下虚拟内存管理
- hadoop过程