3 回答
TA贡献1836条经验 获得超3个赞
一、指代不同
1、shutdown() :是指禁止在一个套接口上进行数据的接收与发送。
2、close():关闭一个套接口。更确切地说,它释放套接口描述字s,以后对s的访问均以WSAENOTSOCK错误返回。
二、原理不同
1、shutdown() :how参数为0,则该套接口上的后续接收操作将被禁止。这对于低层协议无影响。对于TCP协议,TCP窗口不改变并接收前来的数据(但不确认)直至窗口满。对于UDP协议,接收并排队前来的数据。任何情况下都不会产生ICMP错误包。
2、close():为对套接口的最后一次访问,则相应的名字信息及数据队列都将被释放。closesocket()的语义受SO_LINGER与SO_DONTLINGER选项影响。
三、特点不同
1、shutdown() :一个应用程序不应依赖于重用一个已被shutdown()禁止的套接口。特别地,一个WINDOWS套接口实现不必支持在这样的套接口上使用connect()调用。
2、close():如无错误发生,则closesocket()返回0。否则的话,返回SOCKET_ERROR错误,应用程序可通过WSAGetLastError()获取相应错误代码。
TA贡献1829条经验 获得超7个赞
下面说说close和shutdown两个函数的差别,两个函数在网络编程中都被人为是来关闭套接字的,差别如下:
1.操作本质不同
close是文件系统VFS的一个通用函数
shutdown是专门针对socket套接字设立的函数
SOCKET在unix中本就是以文件的形式呈现给大家的,在每创建一个socket时,会对应创建一个文件与之对应,返回文件描述符,
具体的结构在此不详述,在调用close时实际是关闭了减少了文件描述符,当文件描述符引用为0时,则会删除文件,关闭套接字。
而shutdown是直接对socket的操作,相当于设置了socket的属性,可以设置为只读,只写,或者直接关闭,但不会操作与此socket相关
的文件
2.两者操作的效果一同
close的操作跟设置选项LINGER有关,此选项是设置当用户调用close后是否等待把当前缓冲区的数据发送完毕后再关闭套接字
LINGER结构有两个值,一个是on,一个是time
当on为0时,默认情况,用户发送完分组,然后发送FIN分组
当on为1时,time为0,则用户直接发送RST分组
当on为1时,time为非0,则用户等待time值然后发送FIN分组,如果time到了但用户没有发送完数据,则返回错误EWOULDBLOCK
SHUTDOWN
SHUT_RD,套接字不能再发出接收请求,进程仍然可以往套接字发送数据,套接字接收缓冲区中所有数据被丢弃,再接收到的任何数据由TCP丢弃,对套接字发送缓冲区没有任何影响
SHUT_WD ,套接字不能再发出发送请求,套接字发送缓冲区的数据将被发送到对端,然后跟着正常的FIN终止序列
TA贡献1841条经验 获得超3个赞
当所有的数据操作结束以后,你可以调用close()函数来释放该socket,从而停止在该socket上的任何数据操作:close(sockfd);
你也可以调用shutdown()函数来关闭该socket。但是该函数允许你只停止在某个方向上的数据传输,而一个方向上的数据传输继续进行。如你可以关 闭某socket的写操作而允许继续在该socket上接受数据,直至读入所有数据。
int shutdown(int sockfd,int how);
Sockfd是需要关闭的socket的描述符。参数 how允许为shutdown操作选择以下几种方式:
SHUT_RD:关闭连接的读端。也就是该套接字不再接受数据,任何当前在套接字接受缓冲区的数据将被丢弃。进程将不能对该套接字发出任何读操作。对 TCP套接字该调用之后接受到的任何数据将被确认然后无声的丢弃掉。
SHUT_WR:关闭连接的写端,进程不能在对此套接字发出写操作
SHUT_RDWR:相当于调用shutdown两次:首先是以SHUT_RD,然后以SHUT_WR
使用close中止一 个连接,但它只是减少描述符的参考数,并不直接关闭连接,只有当描述符的参考数为0时才关闭连接。
shutdown可直接关闭描述符,不考虑描述 符的参考数,可选择中止一个方向的连接。
注意:
1>. 如果有多个进程共享一个套接字,close每被调用一次,计数减1,直到计数为0时,也就是所用进程都调用了close,套接字将被释放。
2>. 在多进程中如果一个进程中shutdown(sfd, SHUT_RDWR)后其它的进程将无法进行通信. 如果一个进程close(sfd)将不会影响到其它进程. 得自己理解引用计数的用法了
- 3 回答
- 0 关注
- 335 浏览
添加回答
举报