在模式下并没有同样的IP地址和端口号的其他套接口
所有的同一个IP地址和端口号的套接口必须将SO_REUSEADDR选项设置为TRUE
这就意味着一个指定的IP地址和端口号对上只可以用一个器。如果这样的套接口已经存在,那么设置这样的选项将不会达到我们的目的。
只有所有存在的同一个地址和端口号的套接口有这个选项设置,将SO_REUSEADDR设置为TRUE才会有效。如果存在的套接口没有这个选项设置,那么bind函数就会继续并且会返回一个错误号。
下面的代码显示如何将这个选项设置为TRUE:
#define TRUE 1
#define FALSE 0
int z; /* Status code */
int s; /* Socket number */
int so_reuseaddr = TRUE;
z = setsockopt(s,SOL_SOCKET,SO_REUSEADDR,
&so_reuseaddr,
sizeof so_reuseaddr);
如果需要SO_REUSEADDR选项可以由getsockopt函数进行查询。
设置SO_LINGER选项
另一个常用的选项就是SO_LINGER选项。与SO_REUSEADDR选项所不同的是这个选项所用的数据类型并不是一个简单的int类型。
SO_LINGER选项的目的是控制当调用close函数时套接口如何关闭。这个选项只适用于面向连接的协议,例如TCP。
内核的默认行为是允许close函数立即返回给调用者。如果可能任何未发送的TCP/IP数据将会进行传送,但是并不会保证这样做。因为close函数会立即向调用者返回控制权,程序并没有办法知道最后一位的数据是否进行了发送。
SO_LINGER选项可以作用在套接口上,来使得程序阻塞close函数调用,直到所有最后的数据传送到远程端。而且,这会保证两端的调用知道套接口正常关闭。如果失败,指定的选项超时,并且向调用程序返回一个错误。
通过使用不同的SO_LINGER选项值,可以应用一个最后场景。如果调用程序希望立即中止通信,可以在linger结构中设置合适的值。然后,一个到close的调用会初始化一个通信中止连接,而丢弃所有未发送的数据,并立即关闭套接口。
SO_LINGER的这种操作模式是由linger结构来控制的:
struct linger {
int l_onoff;
int l_linger;
};
成员l_onoff为一个布尔值,非零值表示TRUE,而零则表示FALSE。这个选项的三个值描述如下:
1 设置l_onoff为FALSE使得成员l_linger被忽略,而使用默认的close行为。也就是说,close调用会立即返回给调用者,如果可能将会传输任何未发送的数据。
2 设置l_onoff为TRUE将会使得成员l_linger的值变得重要。当l_linger非零时,这代表应用在close函数调用上的以秒计的超时时限。如果超时发生之前,有未发送的数据并且成功关闭,函数将会成功返回。否则,将会返回错误,而将变量errno的值设置为EWOULDBLOCK。setsockopt
3 将l_onoff设置为TRUE而l_linger设置为零时使得连接中止,在调用close时任何示发送的数据都会丢弃。
我们也许希望得到一些建议,在我们的程序中使用SO_LINGER选项,并且提供一个合理的超时时限。然后,可以检测由close函数的返回值来确定连接是否成功关闭。如果返回了一个错误,这就告知我们的程序也许远程程序并不能接收我们发送的全部数据。相对的,他也许仅意味着连接关闭时发生的问题。
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/ruanjian/article-49663-7.html