socket中close()和shutdown()区别

基本TCP程序socket函数

这里写图片描述

并发服务器

Unix中编写并发服务器最简单的办法是fork一个子进程来服务每个客户。
当一个连接建立时,accept返回,服务器接着调用fork,然后由子进程服务客户(通过已连接的套接字connfd),父进程则等待另一个连接(通过监听套接字listenfd)。新的客户由子进程提供服务,父进程就关闭已连接套接字。

如图:
1、服务器接收了一个客户请求
这里写图片描述
2、服务器调用fork,此时listenfd和connfd这两个描述符都在父进程和子进程之间共享(被复制)。
这里写图片描述
3、父进程关闭已连接套接字(connfd),由子进程关闭监听套接字(listenfd)
这里写图片描述

最终子进程处理与客户的连接,父进程则可以在监听套接字上在此调用accept来处理下一个客户连接。

close函数

close函数是用来关闭套接字

int close(int sockfd);

成功返回0,出错为-1

关闭已连接的套接字只是导致相应描述符的引用计数减1,如果引用计数扔大于0,这个close调用并不会让TCP连接上发送一个FIN。如果确实像发送一个FIN,可以用shutdown函数。

回到刚刚并发服务器的过程,第二步fork返回后,connfd和listenfd的引用计数均为2。第三步,父进程close套接字connfd,子进程close套接字listenfd后,connfd和listenfd的引用计数均为1。而该套接字真正的关闭是等于0才发生的。

需要注意的是第三步如果父进程对每个accept返回的已连接套接字connfd都不调用close,那么父进程最终将耗尽可用描述符,而且没有一个客户连接会被终止。因为子进程关闭connfd时,它的引用计数将由2减为1,因为父进程永不关闭任何已连接套接字。

shutdown函数

int shutdown(int sockfd,int howto);

成功返回0,出错返回-1

该函数的行为依赖howto参数的值:

  • SHUT_RD
    套接字中不再有数据可接收,而且套接字接收缓冲区中的现有数据都被丢弃。

  • SHUT_WR
    对于TCP套接字,称为半关闭(half-close)。当前在套接字发送缓冲区中的数据将被发送掉,后跟TCP的正常连接终止序列。(不管套接字的引用计数是否等于0)

  • SHUT_RDWR
    等于调用shutdown函数两次,连接的读半部和写半部都关闭。

区别

  • close把描述符的引用计数减1,仅在该计数变为0时关闭套接字。shutdown可以不管引用计数就激发TCP的正常连接终止序列

  • close终止读和写两个方向的数据发送。TCP是全双工的,有时候需要告知对方已经完成了数据传送,即使对方仍有数据要发送给我们。

  • 8
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在Socket编程shutdown()和close()都是用来关闭一个套接字(Socket)的方法,但二者有不同的作用。 shutdown()方法是用来关闭一个已连接的套接字,它可以在客户端和服务器端分别调用。shutdown()的调用会使得套接字不能再进行数据的发送和接收,但它可以继续进行一些管理操作,例如可以发送一些控制信息给对方,告知对方套接字已关闭。 而close()方法是用来关闭一个套接字的连接,它可以在客户端和服务器端分别调用。调用close()方法后,套接字不再使用,也不会再接收或发送数据。当客户端调用close()时,它会向服务器发送一个关闭连接的请求,服务器收到请求后也会调用close()方法关闭套接字。 ### 回答2: 在Socket编程shutdownclose都是用于关闭连接的方法,但它们有一些区别。 首先,shutdown是用于半关闭连接的操作,它可以关闭Socket的输入和输出流的其一方。shutdown方法可以接受一个参数,该参数可以是常量Socket.SHUT_RD,用于关闭输入流;也可以是常量Socket.SHUT_WR,用于关闭输出流;还可以是常量Socket.SHUT_RDWR,用于关闭输入和输出流。通过这种方式,可以控制关闭连接的一方。 相比之下,close是用于完全关闭连接的操作,它会关闭Socket的输入和输出流,并释放相关的资源。调用close方法后,再次尝试使用该Socket将会抛出异常。 其次,shutdown可以在一个Socket处于连接状态时多次调用,并且可以对输入和输出流进行独立的关闭,而close方法只能在一个Socket连接被完全关闭后调用一次。 最后,通过调用shutdown方法关闭连接,可以保留Socket的状态信息和相关资源,并继续使用该Socket进行数据传输。而调用close方法关闭连接则会释放Socket相关的资源,并且无法再次使用该Socket。 综上所述,shutdownclose方法在Socket编程都可以用于关闭连接,但shutdown方法可以控制关闭连接的一方,可以多次调用并保留Socket状态,而close方法只能完全关闭连接并释放相关资源。 ### 回答3: 在Socket编程shutdown()和close()是两个不同的方法,用于关闭连接和释放Socket资源。 shutdown()方法用于关闭已连接的Socket连接,它需要传入一个参数,来指定关闭的方式。参数可以是SHUT_RD、SHUT_WR或SHUT_RDWR。SHUT_RD表示禁止读取数据,SHUT_WR表示禁止写入数据,SHUT_RDWR表示同时禁止读写数据。通过调用shutdown()方法,我们可以选择关闭连接的读端、写端或者同时关闭两者,这样就可以保持双方的连接而不再传输数据。 相比之下,close()方法是用于完全关闭Socket连接,它不需要传入任何参数。调用close()方法会立即关闭Socket连接,并释放所有与该Socket相关的资源。关闭连接后,将无法再进行读取或写入操作,也无法再建立连接。 总结来说,shutdown()方法是暂时关闭Socket连接的一种手段,可以选择性地关闭读端、写端或者两者。而close()方法是永久关闭Socket连接,并释放相关资源的一种方式。关闭连接后,将无法再进行数据传输或者建立新的连接。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值