代码改变世界

第七章 套接字选项

2017-12-04 22:42  szn好色仙人  阅读(186)  评论(0编辑  收藏  举报
//1.
SO_BROADCAST
本选项开启或禁止进程发送广播消息的能力。只有数据报套接字支持广播,并且只有在支持广播消息的网络上

//2.
SO_DONTROUTE
Indicates that outgoing data should be sent on whatever interface the socket is bound to and not a routed on some other interface. 
This option is only Valid for message-oriented protocols. 
Microsoft providers silently ignore this option and always consult the routing table to find the appropriate outgoing interface.

//3.
SO_ERROR
Returns the last error code on this socket. This per-socket error code is not always immediately set.

//4.
SO_KEEPALIVE
给TCP套接字设置保活选项后,如果2小时内在该套接字的任一方向上都没有数据交换,TCP就自动给对端发送一个保活探测分节。这是一个对端必须响应的TCP分节,
他会导致以下三种情况:
(A):对端以期望的ACK响应,应用进程得不到通知(因为一切正常)。在又经过仍无动静的2小时后,TCP将发送另一个探测分节
(B):对端以RST响应,他告知本端TCP:对端TCP已崩溃且重启
(C):对端无反应,TCP将发送另外指定个数的探测分节,若一直无反应则放弃
备注:对 SO_KEEPALIVE 进行测试 在利用 SIO_KEEPALIVE_VALS 更改默认设置后再次设置, 研究 SIO_KEEPALIVE_VALS 对默认的更改,是否只是针对单个连接的
备注:P159页有疑问
//参考资料 https://msdn.microsoft.com/en-us/library/windows/desktop/dd877220(v=vs.85).aspx

//5.
SO_LINGER
struct  linger {
	u_short l_onoff;                /* option on/off */
	u_short l_linger;               /* linger time */
};
(A):当 l_onoff 为0,则TCP默认设置生效, close 立刻返回,但是有数据残留在套接字发送缓冲区中,系统将试图把这些数据发送给对端。
(B):当 l_onoff 不为0, l_linger 为0,那么当 close 某个连接时,TCP将终止该连接。此时TCP将丢弃所有发送缓冲区中的数据,并发送RST给对方,
	而没有通常的终止的四分节数据,将避免产生 TIME_WAIT 状态
(C):当 l_onoff 不为0, l_linger 不为0,那么当套接字关闭时内核将拖延一段时间,直到所有数据发送完或者延滞时间到。如果套接字被设为非阻塞的,
	那么他将不会等待 close 完成,即使延滞时间不为0。如果在数据发送完并被确认前延滞时间到的话, close 将返回错误,且套接字发送缓冲区数据都将被丢弃

close 的默认操作
1.png

设置 SO_LINGER 套接字选项且 l_linger 足够大时候的(发送缓冲区的数据全部被发送) close
2.png

设置 SO_LINGER 套接字选项且 l_linger 值不够大的 close
3.png

当设置了 SO_LINGER 套接字选项后, close 的成功返回只是代表我们先前发送的数据和FIN已由对端TCP确认,而不能告诉我们对端应用程序是否已读取数据
让客户知道服务器已读取其数据的方法是调用 shutdown 并指定 SD_SEND(windows下),而不是调用 close ,并等待对端 close 当地端

使用 shutdown 来获知对方已接收到数据
4.png

备注: SO_LINGER 的不同情况下的测试

//6.
SO_OOBINLINE
Indicates that out-of-bound data should be returned in-line with regular data. 
This option is only valid for connection-oriented protocols that support out-of-band data.

//7.
SO_RCVBUF
The total per-socket buffer space reserved for receives. 
This is unrelated to SO_MAX_MSG_SIZE and does not necessarily correspond to the size of the TCP receive window.

SO_SNDBUF
The total per-socket buffer space reserved for sends. This is unrelated to SO_MAX_MSG_SIZE and does not necessarily correspond to the size of a TCP send window.

TCP套接字缓冲区的大小至少是相应连接的MSS值的四倍

//8.
SO_MAX_MSG_SIZE
Returns the maximum outbound message size for message-oriented sockets supported by the protocol. Has no meaning for stream-oriented sockets.

SOCKET sock = socket(AF_INET, SOCK_DGRAM, 0);
int nValue = 0;
int nLen = 4;
int nRe = getsockopt(sock, SOL_SOCKET, SO_MAX_MSG_SIZE, reinterpret_cast<char*>(&nValue), &nLen);
//nValue = 65507

//9.
SO_RCVLOWAT
A socket option from BSD UNIX included for backward compatibility. This option sets the minimum number of bytes to process for socket input operations.
This option is not supported by the Windows TCP/IP provider. If this option is used on Windows Vista and later,
the getsockopt and setsockopt functions fail with WSAEINVAL.
On earlier versions of Windows, these functions fail with WSAENOPROTOOPT.

SO_SNDLOWAT
A socket option from BSD UNIX included for backward compatibility. This option sets the minimum number of bytes to process for socket output operations.
This option is not supported by the Windows TCP/IP provider. If this option is used on Windows Vista and later, 
the getsockopt and setsockopt functions fail with WSAEINVAL.
On earlier versions of Windows, these functions fail with WSAENOPROTOOPT.

简而言之:windows下 不支持 这两个套接字选项

//10.
SO_RCVTIMEO
The timeout, in milliseconds, for blocking receive calls. The default for this option is zero, which indicates that a receive operation will not time out. 
If a blocking receive call times out, the connection is in an indeterminate state and should be closed.If the socket is created using the WSASocket function, 
then the dwFlags parameter must have the WSA_FLAG_OVERLAPPED attribute set for the timeout to function properly. 
Otherwise the timeout never takes effect.

When using the recv function, if no data arrives during the period specified in SO_RCVTIMEO, the recv function completes. 
In Windows versions prior to Windows 2000, any data received subsequently fails with WSAETIMEDOUT. In Windows 2000 and later, 
if no data arrives within the period specified in SO_RCVTIMEO, the recv function returns WSAETIMEDOUT, and if data is received, recv returns SUCCESS.
If a send or receive operation times out on a socket, the socket state is indeterminate, 
and should not be used; TCP sockets in this state have a potential for data loss, 
since the operation could be canceled at the same moment the operation was to be completed.

SO_SNDTIMEO
The timeout, in milliseconds, for blocking send calls. The default for this option is zero, which indicates that a send operation will not time out. 
If a blocking send call times out, the connection is in an indeterminate state and should be closed.If the socket is created using the WSASocket function, 
then the dwFlags parameter must have the WSA_FLAG_OVERLAPPED attribute set for the timeout to function properly. 
Otherwise the timeout never takes effect.

备注:对这两个套接字选项进行测试

//11.
SO_REUSEADDR
Allows a socket to bind to an address and port already in use. The SO_EXCLUSIVEADDRUSE option can prevent this.

SO_EXCLUSIVEADDRUSE
Prevents any other socket from binding to the same address and port. This option must be set before calling the bind function.

//12.
SO_TYPE
Returns the socket type for the given socket (SOCK_STREAM or SOCK_DGRAM, for example).

//13.
SO_USELOOPBACK
Use the local loopback address when sending data from this socket. This option should only be used when all data sent will also be received locally.
This option is not supported by the Windows TCP/IP provider. If this option is used on Windows Vista and later, 
the getsockopt and setsockopt functions fail with WSAEINVAL. On earlier versions of Windows, these functions fail with WSAENOPROTOOPT.
简而言之 windows 不支持此选项


备注:当前仅关注了 SOL_SOCKET 级别

参考资料
https://msdn.microsoft.com/en-us/library/windows/desktop/ms740532(v=vs.85).aspx