rtspsever网络编程中的socket选项之SO_LINGER

来源:互联网 发布:沈阳淘宝代运营 编辑:程序博客网 时间:2024/05/29 07:48

 通过rtspTransport里面的函数可以发现,这里设置了一个参数,如下:

static void CloseSockid( int socketid ){  //立即进行关闭,同时发送RST  struct linger so_linger;  so_linger.l_onoff = 1;  so_linger.l_linger = 0;  int ret = setsockopt( socketid, SOL_SOCKET, SO_LINGER, &so_linger, sizeof so_linger );  close( socketid );}

这里设置了so_linger的目的是为了发送rst,快速关闭!

从网上的资料可以知道,

socket的选项很多.其中几个比较重要的选项有:SO_LINGER(仅仅适用于TCP,SCTP)

  • SO_LINGER

在默认情况下,当调用close关闭socket的使用,close会立即返回,但是,如果send buffer中还有数据,系统会试着先把send buffer中的数据发送出去,然后close才返回.

 

SO_LINGER选项则是用来修改这种默认操作的.于SO_LINGER相关联的一个结构体如下:

 
  1. #include <sys/socket.h>   
  2. struct linger {  
  3.       int l_onoff  //0=off, nonzero=on(开关)   
  4.       int l_linger //linger time(延迟时间)   
  5. }

 

当调用setsockopt之后,该选项产生的影响取决于linger结构体中 l_onoff和l_linger的值:

0 = l_onoff

当l_onoff被设置为0的时候,将会关闭SO_LINGER选项,即TCP或则SCTP保持默认操作:close立即返回.l_linger值被忽略.

l_lineoff值非0,0 = l_linger

当调用close的时候,TCP连接会立即断开.send buffer中未被发送的数据将被丢弃,并向对方发送一个RST信息.值得注意的是,由于这种方式,是非正常的4中握手方式结束TCP链接,所以,TCP连接将不会进入TIME_WAIT状态,这样会导致新建立的可能和就连接的数据造成混乱。

 

  • l_onoff和l_linger都是非0

在这种情况下,会使得close返回得到延迟。调用close去关闭socket的时候,内核将会延迟。也就是说,如果send buffer中还有数据尚未发送,该进程将会被休眠直到一下任何一种情况发生:

 

1)    send buffer中的所有数据都被发送并且得到对方TCP的应答消息(这种应答并不是意味着对方应用程序已经接收到数据,在后面shutdown将会具体讲道)
2)    延迟时间消耗完。在延迟时间被消耗完之后,send buffer中的所有数据都将会被丢弃。

 

上面1),2)两种情况中,如果socket被设置为O_NONBLOCK状态,程序将不会等待close返回,send buffer中的所有数据都将会被丢弃。所以,需要我们判断close的返回值。在send buffer中的所有数据都被发送之前并且延迟时间没有消耗完,close返回的话,close将会返回一个EWOULDBLOCK的error.

下面用几个实例来说明:


A.    Close默认操作:立即返回

                                          

此种情况,close立即返回,如果send buffer中还有数据,close将会等到所有数据被发送完之后之后返回。由于我们并没有等待对方TCP发送的ACK信息,所以我们只能保证数据已经发送到对方,我们并不知道对方是否已经接受了数据。由于此种情况,TCP连接终止是按照正常的4次握手方式,需要经过TIME_WAIT。

 

   B.    l_onoff非0,并且使之l_linger为一个整数

 

 

                                         

在这种情况下,close会在接收到对方TCP的ACK信息之后才返回(l_linger消耗完之前)。但是这种ACK信息只能保证对方已经接收到数据,并不保证对方应用程序已经读取数据。


C.    l_linger设置值太小

 

 

                                          

 

这种情况,由于l_linger值太小,在send buffer中的数据都发送完之前,close就返回,此种情况终止TCP连接,更l_linger = 0类似,TCP连接终止不是按照正常的4步握手,所以,TCP连接不会进入TIME_WAIT状态,那么,client会向server发送一个RST信息.

 

D.    Shutdown,等待应用程序读取数据

 

 

 

                                         

同上面的B进行对比,调用shutdown后紧接着调用read,此时read会被阻塞,直到接收到对方的FIN,也就是说read是在server的应用程序调用close之后才返回的。当server应用程序读取到来自client的数据和FIN之后,server会进入一个叫CLOSE_WAIT,那么,如果server端要断开该TCP连接,需要server应用程序调用一次close,也就意味着向client发送FIN。这个时候,说明server端的应用程序已经读取到client发送的数据和FIN。read会在接收到server的FIN之后返回。所以,shutdown 可以确保server端应用程序已经读取数据了,而不仅仅是server已经接收到数据而已。

 

shutdown参数如下:

SHUT_RD:调用shutdown的一端receive buffer将被丢弃掉,无法接受数据,但是可以发送数据,send buffer的数据可以被发送出去

SHUT_WR:调用shutdown的一端无法发送数据,但是可以接受数据.该参数表示不能调用send.但是如果还有数据在send buffer中,这些数据还是会被继续发送出去的.


后面的参考和拷贝来源:http://blog.csdn.net/feiyinzilgd/article/details/5894300


原创粉丝点击