当前位置: 首页 > 编程日记 > 正文

Linux下getsockopt/setsockopt 函数说明

【getsockopt/setsockopt系统调用】  
   
功能描述:
        获取或者设置与某个套接字关联的选 项。选项可能存在于多层协议中,它们总会出现在最上面的套接字层。当操作套接字选项时,选项位于的层和选项的名称必须给出。为了操作套接字层的选项,应该 将层的值指定为SOL_SOCKET。为了操作其它层的选项,控制选项的合适协议号必须给出。例如,为了表示一个选项由TCP协议解析,层应该设定为协议 号TCP。


用法:
#include <sys/types.h>
#include <sys/socket.h>

int getsockopt(int sock, int level, int optname, void *optval, socklen_t *optlen);

int setsockopt(int sock, int level, int optname, const void *optval, socklen_t optlen);

参数:  
sock:将要被设置或者获取选项的套接字。
level:选项所在的协议层。
optname:需要访问的选项名。
optval:对于getsockopt(),指向返回选项值的缓冲。对于setsockopt(),指向包含新选项值的缓冲。
optlen:对于getsockopt(),作为入口参数时,选项值的最大长度。作为出口参数时,选项值的实际长度。对于setsockopt(),现选项的长度。


返回说明:


成功执行时,返回0。失败返回-1,errno被设为以下的某个值  
EBADF:sock不是有效的文件描述词
EFAULT:optval指向的内存并非有效的进程空间
EINVAL:在调用setsockopt()时,optlen无效
ENOPROTOOPT:指定的协议层不能识别选项
ENOTSOCK:sock描述的不是套接字


参数详细说明:

level指定控制套接字的层次.可以取三种值:
1)SOL_SOCKET:通用套接字选项.
2)IPPROTO_IP:IP选项.
3)IPPROTO_TCP:TCP选项. 
optname指定控制的方式(选项的名称),我们下面详细解释

optval获得或者是设置套接字选项.根据选项名称的数据类型进行转换


选项名称        说明                  数据类型
========================================================================
            SOL_SOCKET
------------------------------------------------------------------------
SO_BROADCAST      允许发送广播数据            int
SO_DEBUG        允许调试                int
SO_DONTROUTE      不查找路由               int
SO_ERROR        获得套接字错误             int
SO_KEEPALIVE      保持连接                int
SO_LINGER        延迟关闭连接              struct linger
SO_OOBINLINE      带外数据放入正常数据流         int
SO_RCVBUF        接收缓冲区大小             int
SO_SNDBUF        发送缓冲区大小             int
SO_RCVLOWAT       接收缓冲区下限             int
SO_SNDLOWAT       发送缓冲区下限             int
SO_RCVTIMEO       接收超时                struct timeval
SO_SNDTIMEO       发送超时                struct timeval
SO_REUSERADDR      允许重用本地地址和端口         int
SO_TYPE         获得套接字类型             int
SO_BSDCOMPAT      与BSD系统兼容              int
========================================================================
            IPPROTO_IP
------------------------------------------------------------------------
IP_HDRINCL       在数据包中包含IP首部          int
IP_OPTINOS       IP首部选项               int
IP_TOS         服务类型
IP_TTL         生存时间                int
========================================================================
            IPPRO_TCP
------------------------------------------------------------------------
TCP_MAXSEG       TCP最大数据段的大小           int
TCP_NODELAY       不使用Nagle算法             int
========================================================================

返回说明:  
成功执行时,返回0。失败返回-1,errno被设为以下的某个值  
EBADF:sock不是有效的文件描述词
EFAULT:optval指向的内存并非有效的进程空间
EINVAL:在调用setsockopt()时,optlen无效
ENOPROTOOPT:指定的协议层不能识别选项
ENOTSOCK:sock描述的不是套接字

SO_RCVBUF和SO_SNDBUF每个套接口都有一个发送缓冲区和一个接收缓冲区,使用这两个套接口选项可以改变缺省缓冲区大小。

// 接收缓冲区
int nRecvBuf=32*1024;         //设置为32K
setsockopt(s,SOL_SOCKET,SO_RCVBUF,(const char*)&nRecvBuf,sizeof(int));


//发送缓冲区
int nSendBuf=32*1024;//设置为32K
setsockopt(s,SOL_SOCKET,SO_SNDBUF,(const char*)&nSendBuf,sizeof(int));

注意:

当设置TCP套接口接收缓冲区的大小时,函数调用顺序是很重要的,因为TCP的窗口规模选项是在建立连接时用SYN与对方互换得到的。对于客户,O_RCVBUF选项必须在connect之前设置;对于服务器,SO_RCVBUF选项必须在listen前设置。

结合原理说明:

1.每个套接口都有一个发送缓冲区和一个接收缓冲区。 接收缓冲区被TCP和UDP用来将接收到的数据一直保存到由应用进程来读。 TCP:TCP通告另一端的窗口大小。 TCP套接口接收缓冲区不可能溢出,因为对方不允许发出超过所通告窗口大小的数据。 这就是TCP的流量控制,如果对方无视窗口大小而发出了超过窗口大小的数据,则接 收方TCP将丢弃它。 UDP:当接收到的数据报装不进套接口接收缓冲区时,此数据报就被丢弃。UDP是没有流量控制的;快的发送者可以很容易地就淹没慢的接收者,导致接收方的UDP丢弃数据报。
        2.我们经常听说tcp协议的三次握手,但三次握手到底是什么,其细节是什么,为什么要这么做呢?
        第一次:客户端发送连接请求给服务器,服务器接收;
        第二次:服务器返回给客户端一个确认码,附带一个从服务器到客户端的连接请求,客户机接收,确认客户端到服务器的连接.
        第三次:客户机返回服务器上次发送请求的确认码,服务器接收,确认服务器到客户端的连接.
        我们可以看到:
        1. tcp的每个连接都需要确认.
        2. 客户端到服务器和服务器到客户端的连接是独立的.
        我们再想想tcp协议的特点:连接的,可靠的,全双工的,实际上tcp的三次握手正是为了保证这些特性的实现.


        3.setsockopt的用法

1.closesocket(一般不会立即关闭而经历TIME_WAIT的过程)后想继续重用该socket:
BOOL bReuseaddr=TRUE;
setsockopt(s,SOL_SOCKET ,SO_REUSEADDR,(const char*)&bReuseaddr,sizeof(BOOL));


2. 如果要已经处于连接状态的soket在调用closesocket后强制关闭,不经历TIME_WAIT的过程:
BOOL bDontLinger = FALSE;
setsockopt(s,SOL_SOCKET,SO_DONTLINGER,(const char*)&bDontLinger,sizeof(BOOL));


3.在send(),recv()过程中有时由于网络状况等原因,发收不能预期进行,而设置收发时限:
int nNetTimeout=1000;//1秒
//发送时限
setsockopt(socket,SOL_S0CKET,SO_SNDTIMEO,(char *)&nNetTimeout,sizeof(int));
//接收时限
setsockopt(socket,SOL_S0CKET,SO_RCVTIMEO,(char *)&nNetTimeout,sizeof(int));


4.在send()的时候,返回的是实际发送出去的字节(同步)或发送到socket缓冲区的字节
(异步);系统默认的状态发送和接收一次为8688字节(约为8.5K);在实际的过程中发送数据
和接收数据量比较大,可以设置socket缓冲区,而避免了send(),recv()不断的循环收发:
// 接收缓冲区
int nRecvBuf=32*1024;//设置为32K
setsockopt(s,SOL_SOCKET,SO_RCVBUF,(const char*)&nRecvBuf,sizeof(int));
//发送缓冲区
int nSendBuf=32*1024;//设置为32K
setsockopt(s,SOL_SOCKET,SO_SNDBUF,(const char*)&nSendBuf,sizeof(int));


5. 如果在发送数据的时,希望不经历由系统缓冲区到socket缓冲区的拷贝而影响
程序的性能:
int nZero=0;
setsockopt(socket,SOL_S0CKET,SO_SNDBUF,(char *)&nZero,sizeof(nZero));


6.同上在recv()完成上述功能(默认情况是将socket缓冲区的内容拷贝到系统缓冲区):
int nZero=0;
setsockopt(socket,SOL_S0CKET,SO_RCVBUF,(char *)&nZero,sizeof(int));


7.一般在发送UDP数据报的时候,希望该socket发送的数据具有广播特性:
BOOL bBroadcast=TRUE;
setsockopt(s,SOL_SOCKET,SO_BROADCAST,(const char*)&bBroadcast,sizeof(BOOL));


8.在client连接服务器过程中,如果处于非阻塞模式下的socket在connect()的过程中可以设置connect()延时,直到accpet()被呼叫(本函数设置只有在非阻塞的过程中有显著的作用,在阻塞的函数调用中作用不大)
BOOL bConditionalAccept=TRUE;
setsockopt(s,SOL_SOCKET,SO_CONDITIONAL_ACCEPT,(const char*)&bConditionalAccept,sizeof(BOOL));


9.如果在发送数据的过程中(send()没有完成,还有数据没发送)而调用了closesocket(),以前我们一般采取的措施是"从容关闭"shutdown(s,SD_BOTH),但是数据是肯定丢失了,如何设置让程序满足具体应用的要求(即让没发完的数据发送出去后在关闭socket)?
struct linger {
u_short l_onoff;
u_short l_linger;
};
linger m_sLinger;
m_sLinger.l_onoff=1;//(在closesocket()调用,但是还有数据没发送完毕的时候容许逗留)
// 如果m_sLinger.l_onoff=0;则功能和2.)作用相同;
m_sLinger.l_linger=5;//(容许逗留的时间为5秒)
setsockopt(s,SOL_SOCKET,SO_LINGER,(const char*)&m_sLinger,sizeof(linger));

转载于:https://www.cnblogs.com/qq78292959/archive/2012/03/22/2411390.html

相关文章:

【蓝桥java】进制与整除之最大公约数 最小公倍数

补充&#xff1a; &#xff08;1&#xff09;欧几里得定理&#xff08;辗转相除法&#xff09;&#xff1a;A和B的最大公约数 B和A%B 的最大公约数 &#xff08;2&#xff09;将两个数乘起来再除以最大公约数就是最小公倍数 package cn.zzunit.jnvi;/***寻找最大公约数* autho…

学习C#要养成的好习惯

1. 避免将多个类放在一个文件里面。2. 一个文件应该只有一个命名空间&#xff0c;避免将多个命名空间放在同一个文件里面。3. 一个文件最好不要超过500行的代码&#xff08;不包括机器产生的代码&#xff09;。4. 一个方法的代码长度最好不要超过25行。5. 避免方法中有超过5个参…

3.1、final、finally、 finalize

final 可以用来修饰类、方法、变量&#xff0c;分别有不同的意义&#xff0c;final 修饰的 class 代表不可以继承扩展&#xff0c;final 的变量是不可以修改的&#xff0c;而 final 的方法也是不可以重写的&#xff08;override&#xff09;。 finally 则是 Java 保证重点代码一…

Android模拟器学framework和driver之传感器篇1(linux sensor driver)

对于android模拟器开发环境的搭建这里我就不多说了&#xff0c;网上google下一大堆&#xff0c;还有就是android 模拟器的kernel使用的是goldfish的kernel&#xff0c;可以使用git得到源码&#xff0c;然后就可以编译了&#xff0c;大家还是可以参考罗老师的博客。。。 在这里我…

【java】Lombok的使用

介绍&#xff1a;lombok在编译entity文件时自动生成get set toString hashCode等方法&#xff0c;这样方法生成就不用写在代码里了&#xff0c;可以简化代码。 使用方法&#xff1a; 一、在pom文件里引入lombok的依赖 代码实现&#xff1a; <dependency><groupId&g…

自己开发开源jquery插件--给jquery.treeview加上checkbox

很多时候需要把树状的数据显示除来&#xff0c;比如分类&#xff0c;中国省份、城市信息&#xff0c;等&#xff0c;因此这方面的javascript插件也有很多.比如性能优异的jquery.treeview和国人开发的功能强大的zTree. 我最近在一个项目中用到了jquery.treeview&#xff0c;但是…

SQL Server 2000安装时不出现安装界面,进程中存在解决

在XP和Server 2003系统中安装SQL Server 2000过程中&#xff0c;点击安装后&#xff0c;一直不出现安装界面&#xff0c;查看进程中也有&#xff0c;一直无反应。 解决办法&#xff1a; 首先重新启动机器&#xff0c;或者任务管理器里面结束2个sql进程 1. 在 SQLServer 安装向导…

Apache2.4部署python3.6+django2.0项目

一、安装apache Apache是非常有名的web服务器软件&#xff0c;如果想让我们web项目运行几乎离不开它。 Apache官方网站&#xff1a;http://httpd.apache.org/ 根据自己的环境&#xff0c;选择相应的版本进行下载。apache 官网没有windows 64位版本&#xff0c;可以通过下面的链…

我是如何有效的避免测试漏测?

漏测&#xff0c;指在产品缺陷在测试过程中没有被发现&#xff08;尤其是测试环境可以重现的缺陷&#xff09;&#xff0c;而是在版本发布后或者在用户使用后发现并反馈回来的缺陷。可以说&#xff0c;漏测的问题是测试管理者最头痛的问题。因为出现漏测&#xff0c;一来给客户…

总结是学习最好的方式(转)

总结是学习最好的方式 最近一直想总结来华为公司这3个多月自己有什么收获&#xff0c;但又想不明白自己收获了什么&#xff1f;说技术吧&#xff0c;也谈不上有多大的提高&#xff1b;说人际交流&#xff0c;也许还有些退步&#xff1b;说薪资存款吧&#xff0c;哎不谈了。想着…

【转载】JUnit各个注解的含义

转自&#xff1a;https://blog.csdn.net/weixin_38500014/article/details/84393775

silverlight、wpf中 dispatcher和timer区别

相同点&#xff1a;都是定时执行任务的计时器&#xff0c;都可以使用。 不同点&#xff1a;Timer运行在非UI 线程&#xff0c;如果Timer需要更新UI的时候&#xff0c;需要调用 Invoke或者 BeginInvoke DispatcherTimer运行在UI 线程&#xff0c;处理的 Dispatcher 队列中的计时…

web开发基础

web开发:所谓web开发就是基于浏览器服务器的开发下面将web开发基础知识作个总结:1.http协议:是建立在TCP协议上的,基于请求响应的模型2.http请求:面试题:说说get与post的区别a.传递数据量:get只能传递1kb以下的数据,post可以传递大数据b.安全性:get请求,如果携带参数,参数会直接…

让ubuntu下的eclipse支持GBK编码

原创作品&#xff0c;允许转载&#xff0c;转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://leaze.blog.51cto.com/83088/195584今天&#xff0c;把windows下的工程导入到了Linux下eclipse中&#xff0c;由于以前的工程代码&#x…

Session,ViewState用法

Session,ViewState用法基本理论&#xff1a; session值是保存在服务器内存上,那么,可以肯定,大量的使用session将导致服务器负担加重. 而viewstate由于只是将数据存入到页面隐藏控件里,不再占用服务器资源,因此, 我们可以将一些需要服务器"记住"的变量和对象保存到vi…

【HTML】记录自己丢人过程:文本换行缩进都不会

问题描述&#xff1a; html文本想实现换行和缩进&#xff0c;最后气到摔鼠标 换行 实现代码&#xff1a; <br> 直接在文本后加个换行标签即可 缩进 实现代码&#xff1a; style"text-indent: 2em;" 注意&#xff1a;这个属性放到p标签中或者div标签中都…

CentOS5.6系统下mysql5安装

我的系统是CentOS5.6 建议大家完全安装&#xff0c;以免安装时缺少相关的编译器等等。 一、安装mysql&#xff08;mysql-5.1.50.tar.gz&#xff09; # tar zxf mysql-5.1.50.tar.gz # cd mysql-5.1.50 #./configure --prefix/usr/local/mysql --sysconfdir/etc --localstated…

CentOS 6.9/7通过yum安装指定版本的JDK/Maven

说明&#xff1a;通过yum好处其实很多&#xff0c;环境变量不用配置&#xff0c;配置文件放在大家都熟悉的地方&#xff0c;通过rpm -ql xxx可以知道全部文件的地方等等。 一、安装JDK&#xff08;Oracle JDK 1.8&#xff09; # wget --no-check-certificate --no-cookies --he…

2019牛客全国多校训练三 题解

A Gragh Games Unsolved. B Crazy Binary String 题解&#xff1a;水题&#xff0c;子序列只要统计0和1数量&#xff0c;取最小值然后乘2就是答案&#xff1b; 对于子串&#xff1a;先记录0和1 前缀和的差值&#xff0c;然后找差值相等的距离最远的两个位置即可&#xff1b; 参…

【硬件基础】有源蜂鸣器与无源蜂鸣器

辨别方法 外观&#xff1a; 无源蜂鸣器: 有源蜂鸣器&#xff1a; 注&#xff1a;可以看到底部有绿色电路板的是无源蜂鸣器&#xff0c;底部是黑胶的为有源蜂鸣器 万用表电阻档检测 无源蜂鸣器&#xff1a;发出咔、咔声的且电阻只有8Ω&#xff08;或16Ω&#xff09;。 有源…

hdu 1272 小希的迷宫

Problem Description上次Gardon的迷宫城堡小希玩了很久&#xff08;见Problem B&#xff09;&#xff0c;现在她也想设计一个迷宫让Gardon来走。但是她设计迷宫的思路不一样&#xff0c;首先她认为所有的通道都应该是双向连通的&#xff0c;就是说如果有一个通道连通了房间A和B…

技术还是商业重要

在中国IT业创业听得最多的就是&#xff0c;技术不重要&#xff0c;商业和关系才是最重要的。 到了硅谷之后&#xff0c;发现技术气氛十分浓&#xff0c;甚至有朋友说大陆创业比较容易是因为硅谷与之相比&#xff0c;硅谷太注重技术了。 可是慢慢发现其实在硅谷&#xff0c;商业…

bzoj1036: [ZJOI2008]树的统计Count 树链剖分

一棵树上有n个节点&#xff0c;编号分别为1到n&#xff0c;每个节点都有一个权值w。我们将以下面的形式来要求你对这棵树完成一些操作&#xff1a; I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 III. QSUM u v: 询问从点u到点v的…

cocos lua 加密方案

cocos2d使用的是luajit&#xff0c;lua原生编译出来的bytecode和luajit是不兼容的&#xff0c;所以直接用luac法编译出来的bytecode脚本无法在cocos2d中使用。 目前所指的解决方案有2个&#xff1a; A.luajit加密&#xff1a; 1、官网下载luajit&#xff08;http://luajit.org/…

VS2010创建ATL类时需要手动填写ProgID

在新建ATL类的时候VS2010默认是不填写ProgID的&#xff1a; 所以默认创建的类生成的rgs文件中只有NoRemove CLSID这一栏&#xff0c;导致在JS中使用new ActivexObject(“LibName.ClassName”)失败。如果想用ActivexObject创建类的话就必须填写ProgID。转载于:https://www.cnblo…

【官网搭建】在网站首页底部添加备案号链接至工信部首页及版权所有。

在网站首页底部添加备案号链接至工信部首页及版权所有。&#xff08;工信部链接&#xff1a;http://beian.miit.gov.cn或http://www.beian.miit.gov.cn&#xff09; 在搭建网址的时候你是否受到过这种邮件&#xff1f; 下面提供一个代码模板 <div class"foot_bot&quo…

如何在linux下解压缩rar格式的文件压缩包

前言&#xff1a;没有特殊原因&#xff0c;文档如果要传到linux上&#xff0c;一定要打成*.zip格式&#xff0c; 这样方便解压&#xff0c;一般来说没有理由要用rar.关于 linux上unzip命令有空细讲&#xff0c; 本节讲下&#xff0c;如何让linux支持解压缩rar文件 一 、系统环境…

appium+python自动化45-夜神模拟器连不上(adb server version (36) doesn't match this client (39); killing...)...

前言 最新下了个最新版的夜神模拟器&#xff0c;然后adb devices发现连不上模拟器了&#xff0c;报adb server version (36) doesnt match this client (39); killing... 从报错信息看是adb版本不匹配导致的&#xff0c;接下来讲如何解决这个问题 环境&#xff1a; 夜神模拟器 …

Android.mk文件语法规范

序言&#xff1a; ------------- 此文档旨在描述Android.mk文件的语法&#xff0c;Android.mk文件为Android NDK(原生开发&#xff09;描述了你C/C源文件。为了明白下面的内容&#xff0c;你必须已经阅读了docs/OVERVIEW.TXT的内容&#xff0c;它解释了Android.mk文件扮演的角色…

【硬件基础】制作直流电源

要求&#xff08;其实就是个课设&#xff09;&#xff1a; 利用二极管的基本特性、三极管的基本特性、稳压电源等知识&#xff0c;设计相 应的模拟电路&#xff0c;设计制作放大倍数可变的直流放大器。 任务要求&#xff1a; &#xff08;1&#xff09;用集成芯片制作一个 0~1…