setsocketopt()

在TCP连接中,recv等函数默认为阻塞模式(block),即直到有数据到来之前函数不会返回,而我们有时则需要一种超时机制使其在一定时间后返回而不管是否有数据到来,这里我们就会用到setsockopt()函数:
    int  setsockopt(int  s, int level, int optname, void* optval, socklen_t* optlen);

这里我们要涉及到一个结构:
    struct timeval
    {
            time_t tv_sec;
            time_t tv_usec;
    };
    这里第一个域的单位为秒,第二个域的单位为微秒。
    struct timeval tv_out;
    tv_out.tv_sec = 1;
    tv_out.tv_usec = 0;

填充这个结构后,我们就可以以如下的方式调用这个函数:
    setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv_out, sizeof(tv_out));

这样我们就设定了recv()函数的超时机制,当超过tv_out设定的时间而没有数据到来时recv()就会返回0值。

选项 类型 意义

SO_BROADCAST BOOL 允许套接口传送广播信息。

SO_DEBUG BOOL 记录调试信息。

SO_DONTLINER BOOL 不要因为数据未发送就阻塞关闭操作。设置本选项相当于将SO_LINGER的l_onoff元素置为零。

SO_DONTROUTE BOOL 禁止选径;直接传送。

SO_KEEPALⅣE BOOL 发送“保持活动”包。

SO_LINGER struct linger FAR* 如关闭时有未发送数据,则逗留。

SO_OOBINLINE BOOL 在常规数据流中接收带外数据

SO_RCVBUF int 为接收确定缓冲区大小。

SO_REUSEADDR BOOL 允许套接口和一个已在使用中的地址捆绑(参见bind())。

SO_SNDBUF int 指定发送缓冲区大小。

TCP_NODELAY BOOL 禁止发送合并的Nagle算法

setsockopt()不支持的BSD选项有:

选项名 类型 意义

SO_ACCEPTCONN BOOL 套接口在监听。

SO_ERROR int 获取错误状态并清除。

SO_RCVLOWAT int 接收低级水印

SO_RCVTIMEO int 接收超时。

SO_SNDLOWAT int 发送低级水印。

SO_SNDTIMEO int 发送超时。

SO_TYPE int 套接口类型。

IP_OPTIONS 在IP头中设置选项

第二个我们要介绍的是多路复用机制,也就是同时监听多个套接字连接。
    int select(int n, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, struct timeval* timeout);
    这里涉及到了fd_set结构:
    typedef struct fd_set
    {
            u_int fd_count;
            int fd_array[FD_SETSIZE];
    }

fd_count为fd_set结构中包含的套接字个数,fd_array唯一个int 数组,包含了我们要监听的套接字。
    首先我们需要使用FD_SET将我们要监听的套接字添加到fd_set结构中:

  fd_set readfd;
    FD_SET(fd, &readfd);

然后我们这样调用select函数:
    select(max_fd + 1, &readfd, NULL, NULL, NULL);(具体参数可以man一下,或查看MSDN)
    FD_ISSET(fd, &readfd);

其中max_fd为我们要监听的套接字中值最大的一个,同时在调用select是要将其加1,readfd即为我们监听的要进行读操作的套接字连接,第三个参数是我们监听的要进行写操作的套接字连接,第四个参数用于异常,而最后一个参数可以用来设定超时,这里同样使用了struct timeval结构,可以实现与前面介绍的同样的效果。这里如果连接进来的话select即返回一个大于零的值,然后我们调用FD_ISSET宏来检测具体是那一个套接字有数据进来(FD_ISSET返回非零值)。

 最后介绍的是另一种实现非阻塞的方法,这种方法在有些应用中会起到一定作用,尤其是在select()函数监听的套接字个数超过1024个时(因为fd_set结构在大部分UNIX系统中都对其可以监听的套接字个数作了1024的限制,如果要突破这个限制,必须修改头文件并重新编译内核),我们就不能使用select多路复用机制。
    拿recv()函数来说,我们可以这样进行调用:
    recv(fd, buf, sizeof(buf), MSG_DONTWAIT);
    注意到我们这里采用了MSG_DONTWAIT标志,它的作用是告诉recv()函数如果有数据到来的话就接受全部数据并立刻返回,没有数据的话也是立刻返回,而不进行任何的等待。采用这个机制就可以在多于1024个套接字连接时使用for()循环对全部的连接进行监听。

时间: 2024-10-22 14:11:39

setsocketopt()的相关文章

socket选项总结(setsocketopt)

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

socket相关函数

socket() 我们使用系统调用socket()来获得文件描述符:#include<sys/types.h>#include<sys/socket.h>int socket(int domain,int type,int protocol);第一个参数domain设置为"AF_INET".第二个参数是套接口的类型:SOCK_STREAM或SOCK_DGRAM.第三个参数设置为0.系统调用socket()只返回一个套接口描述符,如果出错,则返回-1 setsoc

Linux编程之UDP SOCKET全攻略

这篇文章将对linux下udp socket编程重要知识点进行总结,无论是开发人员应知应会的,还是说udp socket的一些偏僻知识点,本文都会讲到.尽可能做到,读了一篇文章之后,大家对udp socket有一个比较全面的认识.本文分为两个专题,第一个是常用的upd socket框架,第二个是一些udp socket并不常用但又相当重要的知识点. 一.基本的udp socket编程 1. UDP编程框架要使用UDP协议进行程序开发,我们必须首先得理解什么是什么是UDP?这里简单概括一下. UD

python核心编程--笔记

python核心编程--笔记 的解释器options: 1.1 –d   提供调试输出 1.2 –O   生成优化的字节码(生成.pyo文件) 1.3 –S   不导入site模块以在启动时查找python路径 1.4 –v   冗余输出(导入语句详细追踪) 1.5 –m mod 将一个模块以脚本形式运行 1.6 –Q opt 除法选项(参阅文档) 1.7 –c cmd 运行以命令行字符串心事提交的python脚本 1.8 file   以给定的文件运行python脚本 2 _在解释器中表示最后

Savelog项目总结回忆

Savelog项目的细节已经不太记得,感觉有些遥远,需要翻回旧的笔记本电脑或者是旧的笔记本. 概述: 本项目采用的Linux C,监听一个或多个特殊的端口,当其中一个端口有发起连接时就产生一个新的线程,并将端口发来的数据进行检验,然后保存到日志,日志只保留最近7天的内容,连接的端口会不断的发送数据,大概每秒钟发送一个,发送成功或失败都要写入日志,成功用info标签,记录端口号,IP等,失败根据失败的内容检查,并给出相应的原因. 下面讲一些笔记记下来,是从刚开始学Linux开始的那段. 杂锦: l

setsockopt 设置TCP的选项SO_LINGER

SO_LINGER选项用来设置延迟关闭的时间,等待套接字发送缓冲区中的数据发送完成. 没有设置该选项时,在调用close()后,在发送完FIN后会立即进行一些清理工作并返回.如果设置了SO_LINGER选项,并且等待时间为正值,则在清理之前会等待一段时间. 以调用close()主动关闭为例,在发送完FIN包后,会进入FIN_WAIT_1状态.如果没有延迟关闭(即设置SO_LINGER选项),在调用tcp_send_fin()发送FIN后会立即调用sock_orphan()将sock结构从进程上下

mysql binlog限流问题总结

业务场景: 新建slave连到master,执行start slave时master险些被"搞死". 分析:新建slave连到master时,会将主库上大量的binlog(几百G)拉取到本地保存为relay log,会导致两个问题 1.主库网络带宽被占满 . 2.主库的磁盘I/O负载很高. 解决思路: 1. 在slave拉取master的binlog时,在I/O thread上做限流:每拉取一定数据量master的binlog则sleep时间N. 这个测试效果比较明显,但存在如下几个问

Linux编程设计——套接字

套接字 套接字,另外一种进程间通信的方式.之前的IPC机制只能限定在一台计算机系统上进行资源共享.而套接字接口可以使,一台机器上的进程和另外一个机器上的进程通信. 什么是套接字 套接字是一种通信机制,凭借这种机制,客户/服务器系统的工作即可以在本地单机上工作,也可以跨网络进行. 套接字和管道类型,同样是读写类文件描述符的操作.不同的是,套接字明确的将客户和服务器分开来.套接字机制可以实现多个客户连接一个服务器. 套接字连接 首先,服务器应用程序使用socket来创建一个套接字,它是系统分配给该服

Python之Scanner编写

嗯!拖延症晚期,已经无可救药,熬了两个晚上的夜,基本也把计算机网络课程设计的网络扫描器的功能实现了. 其实,写个扫描器也挺好玩的,牵涉到了RAW Socket编程,可以尽情地DIY数据包(当然,不符合数据包规则,比如checksum错误就没办法了),收获颇深.其中,我觉得用C语言写更有利于在编写过程中对加深对计算机网络的理解,特别是数据包细节.但是由于效率问题,还有Python真是太好用了(自从用了python,日常再也不想去碰C/C++了,虽然python也写的挺烂的).话不多说,言归正传.