SOL_SOCKET协议族选项:通用地址协议族选项
IPPROTO_TCP和IPPROTO_IP选项:涉及到传输层和IP层的套接字选项
ioctl()函数:用户与Linux内核协议栈进行交互的一种方式
——————————SOL_SOCKET协议族选项:——————————
获取和设置套接字选项
SO_KEEPALIVE选项
SO_LINGER选项
SO_RCVBUF和SO_SNDBUF选项
SO_RCVLOWAT和SO_SNDLOWAT选项:低水位选项?
SO_RCVTIMEO和SO_SNDTIMEO选项:超时
SO_REUSEADDR选项:地址重置
获取和设置套接字选项:用来获取或者设置与某个套接字相关的选项
getsockopt()函数和setsockopt()函数原型:
#include
//选项可能存在多层协议中,总会出现在最上面的套接字层。
//当对套接字选项进行操作时必须给出选项所在的层次和选项的名称
//为了操作,应该讲层的值设置为solsocket
//为了操作其它层的选项必须给出控制选项的协议类型号
//第一个参数s表示:将要获取或要设置的套接字描述符
//第二个参数optname值表示:选项名
//optval:表示操作的内存缓冲区
//get:指向用于获取返回选项值的缓冲区
//set:指向用于设置参数的缓冲区
//optlen:表示上一个参数即缓冲区的长度
//get情况下:表示指向socket T类型的指针
//传入参数时:表示传入optval的实际长度
//传出参数时:表示用于保存optval的最大长度
//set情况下:表示第四个参数实际的长度
//成功时返回0失败时返回-1
int getsockopt(int s,int level,int optname,void* optval.socklen_t* optlen);
int setsockopt(int s,int level,int optname,void* optval.socklen_t optlen);
getsockopt()函数和setsockopt()函数错误代码含义:
EBADF:参数s不是有效的文件描述符
EFAULT:optval指向的内存并非有效的进程空间
EINVAL:在调用setsockopt()函数时,optlen无效
ENOPROTOOPT:指向的协议层不能识别选项
ENOTSOCK:s描述的不是套接字描述符
按照参数选项界别level值的不同,套接字选项可以分为3大类:
通用套接选项:level的值为SOL_SOCKET
IP选项:level的值为IPPROTO_IP
TCP选项:level的值为IPPROTO_TCP
SOL_SOCKET协议族选项— SO_KEEPALIVE选项:
一般在服务端设置。用于可能较长时间不通信的连接。
SO_KEEPALIVE保持连接选项,2小时没有数据交互,发送探测报文,有三种回应:
回应一个ACK报文:如果对方发送的是ACK表示对方连接正常,两小时再次发送ACK
回应一个RST报文:如果对方发送的是RST表示对方在两小时内进行了重启或者崩溃
没有任何回应:如果对方没有任何回应,那么就会发送八种活动探测报文,间隔75s。如果发送了第一个探测报文对方没有任何反应,发送方就会放弃探测。同时将套接字错误类型设置为timeout,进而关闭套接字连接。
SO_KEEPALIVE使用方法:
int optval =1;
//SOL_SOCKET:表示通用地址族选项
setsockopt(sockfd,SOL_SOCKET,SO_KEEPALIVE,&optval,sizeof(optval));
SOL_SOCKET协议族选项— SO_LINGER选项:主要用于设置TCP连接close关闭时的行为方式
SO_LINGER缓冲区处理方式选项,它的操作通过一个结构体进行:
struct linger{
int l_onoff; //开启(非0)还是关闭(0)该选项
int l_linger; //滞留时间
};
SO_LINGER选项使用方法有三种:
l_onoff等于0,此时SO_LINGER选项不起作用:close用默认行为关闭套接字
l_onoff不为0,l_linger为0:close系统调用立即返回。TCP将丢弃被关闭的TCP连接中的发送缓冲区中的数据。同时给对方发送一个复位报文段
l_onoff不为0,l_linger不为0:如果阻塞的连接,就等待linger时间,并在此时间内发送缓冲区中的内容,而且得到对方的返回值。如果linger时间内没有发送完内容,也就是没有得到对方返回值,那么close将返回-1。如果是非阻塞的close将立即返回
SO_LINGER使用方法:
optval.l_onoff =1;
optval.l_linger =60;setsockopt(sockfd,SOL_SOCKET,SO_LINGER,&optval,sizeof(optval));
SOL_SOCKET协议族选项— SO_RCVBUF和SO_SNDBUF选项:
SO_RCVBUF和SO_SNDBUF缓冲区大小选项:
//在TCP/UDP连接中的含义不同
//UDP连接中由于是无连接。发送缓冲区在通过网络设备发送数据后就可以丢弃不用保存。而接收缓冲区就需要保存数据知道应用程序读取。由于UDP没有流量控制,当缓冲去过小时,发送区在局部时间内将会产生爆发性数据传输。因此在使用UDP连接时需要将接收缓冲区设置为比较大的值。
//TCP连接时,接受缓冲区的大小就是滑动窗口的大小,接收缓冲区不会溢出,因为发送端不允许发送超过缓冲区大小的数据。
设置TCP/UDP连接的接收/发送缓冲区的含义
//因为接收缓冲区大小和滑动窗口大小是一致的,而滑动窗口的协商是在建立连接时通过同步报文获得的。对于客户端来说,接收缓冲区的大小要在connect系统调用之前进行设置,因为connect需要通过同步报文段建立连接。
//对于服务器端来说,需要在listen之前设置接收缓冲区的大小。因为accept函数返回的套接字描述符是继承了listen的描述符属性。
在connect()函数调用之前设置
SOL_SOCKET协议族选项— SO_RCVTIMEO和SO_SNDTIMEO选项:数据发送接收超时相关
SO_RCVTIMEO表示接收超时的超时时间,SO_SNDTIMEO表示发送超时的超时时间,设置是通过一个结构体来实现:
struct timeval{
time_t tv_sec; 秒数
sseconds_t tv_usec; 微秒
};
SOL_SOCKET协议族选项— SO_RCVLOWAT和SO_SNDLOWAT选项:水位相关?
一般被IO复用用来判断socket是否可用或者是否可写。
当TCP接收缓冲区中可读数据的总数大于其低水位标记时,IO复用系统调用将会通知对应的系统应用程序可以对socket读取数据。
当TCP发送缓冲区中的空闲空间也就是可以写入数据的空间大于其低水位标记时IO复用系统调用将会通知应用程序对对应的socket写入系统数据。
但是在默认情况下,TCP发送缓冲区和接受缓冲区的大小都是一个字节。
SO_RCVLOWAT和SO_SNDLOWAT选项表示接收缓冲区和发送缓冲区的低水位标记。
SOL_SOCKET协议族选项— SO_REUSEADDR选项:地址可重用选项。表示允许重复使用本地地址和端口,在服务器设置中经常使用。允许公用端口。
因为一些端口即使死掉内核也要一段时间处理,才可以绑定到此端口上。使用此选项可以解决这个问题。
经过设置后即使处于timewait状态,与之绑定的套接字地址也可以立即被重用。
也可以通过修改内核参数来快速的回收被关闭的套接字。从而使TCP连接根本就不进入TIME_WAIT状态。进而允许本地应用程序立即重用套接字地址。
SO_REUSEADDR地址可重用选项,设置此选项可以使用被处于TIME_WAIT状态的连接占用的socket地址:
int reuse =1;
Setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse));
示例演示:so_reuseaddr.c
int sock = socket(AF_INET,SOCK_STREAM,0);//盛情套接字
assert(sock >=0);
int reuse = 1;
setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse));//将套接字设置为地址可重用
struct sockaddr_in address;
bzero(&address,sizeof(address));
address.sin_family = AF_INET;
inet_pton(AF_INET,ip,&address.sin_addr);
address.sin_port = htons(port);
int ret = bind(sock,(struct sockaddr*)&address,sizeof(address));
——————————IPPROTO_TCP和IPPROTO_IP选项:——————————
TCP_KEEPALIVE选项
TCP_NODELAY和TCP_CORK选项
IP_TOS选项
IP_TTL选项
IPPROTO_TCP和IPPROTO_IP选项— TCP_KEEPALIVE选项:设置后了才有效,默认7200秒。两小时系统进行一次存活时间的探测
TCP_KEEPALIVE用来获取或设置存活探测的时间间隔:
int alivetime = 60;
int fd = socket(AF_INET,SOCK_STREAM,0);
setsockopt(fd,IPPROTO_TCP,TCP_KEEPALIVE,&alivetime,sizoef(alivetime));
IPPROTO_TCP和IPPROTO_IP选项— TCP_NODELAY和TCP_CORK选项:针对(ngo)算法的关闭而设计的
TCP_NODELAY和TCP_CORK针对Nagle算法,此算法的基本原理如下:
将下分组封装成大的分组再发送
使用延迟确认
TCP_NODELAY选项的作用:
客户端的请求不需要和其他分组合并
TCP_CORK选项的作用
需要等到发送的数据量达到最大是,一次性发送全部数据
IPPROTO_TCP和IPPROTO_IP选项— IP_TOS选项:设置或者获取服务类型的值
服务类型选项:
IPTOS_LOWDELAY:表示最小延迟
IPTOS_RELIABILITY:表示最大可靠性
IPTOS_THROUGHPUT:表示最大吞吐量
IPTOS_LOWCOST:表示最小成本
IPPROTO_TCP和IPPROTO_IP选项— IP_TTL选项:
生成时间选项:
可以获取或设置发送报文的TTL值:一般为64.对于原始套接字,值为255
可以调整网络数据发送的速度:
实例演示:
int current_TTL =0;
int set_TTL = 32;
int length_TTL =sizeof(int);
getsockopt(s,IPPROTO_IP,IP_TTL,¤t_TTL,&lenght_TTL);
setsockopt(s,IPPROTO_IP,IP_TTL,&set_TTL,length_TTL);
sendto(s,buffer,buffer_len,0,(struct sockaddr*)&remote_ip,sizeof(struct sockaddr));
setsockopt(s,IPPROTO_IP,IP_TTL,¤t_TTL,length_TTL);
——————————ioctl()函数:主要用于与Linux内核协议栈进行交互————————
ioctl()函数的命令选项
ioctl()函数的IO请求
ioctl()函数的文件请求
ioctl()函数的网络接口请求
ioctl()函数对ARP高速缓存操作
ioctl()函数— ioctl()函数的命令选项:
ioctl()函数和协议栈交互,主要的交互类型由:
IO
文件
网络接口
路由
ARP
ioctl()函数— ioctl()函数的IO请求:
套接字IO操作的命令请求有6个,第三个参数为整形指针:
SIOCATMARK:查看TCP连接是否有带外数据。如果有带外数据,第三个指针返回数据为非0。
SIOCSPGRP和FIOSETOWN:处理套接字的SIGIO和SIGURG信号。进行处理的进程ID号,进程组ID号。
SIOCGPGRP和FIOGETOWN:设置接收SIGIO信号的进程ID。
SIOCGSTAMP:获取最后一个数据报达到的时间。
ioctl()函数— ioctl()函数的文件请求:
文件请求的命令有3个:除了处理套接字,对通用文件也适用!
FIONBIO:用于设置或清除套接字的非阻塞标志。套接字第三个参数为0时为阻塞方式。非零时为非阻塞方式。
FIOASYNC:设置或者清除套接字的异步信号。也就是信号SIGIO.当第三个参数为0时表示清除异步信号。非零时表示设置。
FIONREAD:获得当前套接字接受缓冲区的字节数
ioctl()函数— ioctl()函数的网络接口请求:
获得网络接口的不同参数的不同命令选项:
SIOCGIFADDR和SIOCSIFADDR:获取和设置本地IP地址
SIOCGIFMTU和SIOCSIFMTU:获取和设置MTU
SIOCGIFHWADDR和SIOCSIFHWADDR:获取和设置硬件地址
ioctl()函数— ioctl()函数对ARP高速缓存操作:
ioctl()函数获取ARP高速缓存,有三个命令字: SIOCDARP:删除高速缓存中的一个记录 SIOCSARP:设置或者修改一个记录 SIOCGARP:获得一个记录