#include
#include
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()获取相应错误代码。
用于设置/读取发送缓冲区和接收缓冲区大小
选项值类型: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));
选项值类型: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));
这个选项被设置后,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));
选项值类型:
struct linger{
int l_onoff; //选项是否有效
int l_linger; //关闭socket的延迟时间
};
可能的情况:
1、l_onoff=0
此时l_linger被忽略,close按默认方式工作;
2、l_onoff非0,l_linger=0
close函数放弃连接向对方发送RST数据段,然后立即关闭socket,释放socket资源,这种情况socket不会进入TIME_WAIT状态,可能会导致以下的问题:
a. 数据丢失(TCP协议丢弃未发送的数据);
b. 连接非正常关闭(调用close的一方发送RST数据段,而不是FIN数据段,导致另一方认为发生错误,非正常关闭连接);
c. 数据混乱(连接双方都不进入TIME_WAIT状态,因此在上次连接的数据没有从网络上消除之前,新的相同连接(IP和端口相同)可以建立,有可能会收到上次连接的数据,导致数据混乱).
3、 l_onoff和l_linger都非0
close函数阻塞,在延迟指定的时间后关闭连接,根据数据是否在延时期间内得到确认正常返回或返回错误EWOULDBLOCK;
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));
1.TCP_MAXSEG:获取和设置一个TCP连接的最大数据段的大小;
2.TCP_NODELAY:用于禁止TCP协议的Nagle算法,使小数据包(小于最大数据段大小)立即发送,会降低TCP协议的效率