socket中shutdown和closesocket的区别

作者&投稿:保翁 (若有异议请与网页底部的电邮联系)
Socket 编程中 close() 和 shutdown() 有什么区别?~

一、指代不同
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()获取相应错误代码。

参考资料来源:百度百科-shutdown()
参考资料来源:百度百科-closesocket()

close(sockfd);关闭socket,不管该socket上是否有没收万的数据,还是未发送的数据,强行关闭socket读和写.int shutdown(int sockfd,int how);关闭socket ,但是要看第二个参数how参数 how允许为shutdown操作选择以下几种方式: SHUT_RD:关闭连接的读端。也就是该套接字不再接受数据,任何当前在套接字接受缓冲区的数据将被丢弃。进程将不能对该套接字发出任何读操作。对 TCP套接字该调用之后接受到的任何数据将被确认然后无声的丢弃掉。 SHUT_WR:关闭连接的写端,进程不能在对此套接字发出写操作 SHUT_RDWR:相当于调用shutdown两次:首先是以SHUT_RD,然后以SHUT_WR

一、从函数调用上来分析(msdn):

一旦完成了套接字的连接,应当将套接字关闭,并且释放其套接字句柄所占用的所有资源。真正释放一个已经打开的套接字句柄的资源直接调用closesocket即可,但要明白closesocket的调用可能会带来负面影响,具体的影响和如何调用有关,最明显的影响是数据丢失,因此一般都要在closesocket之前调用shutdown来关闭套接字。
shutdown:为了保证通信双方都能够收到应用程序发出的所有数据,一个合格的应用程序的做法是通知接受双发都不在发送数据!这就是所谓的“正常关闭”套接字的方法,而这个方法就是由shutdown函数,传递给它的参数有SD_RECEIVE,SD_SEND,SD_BOTH三种,如果是SD_RECEIVE就表示不允许再对此套接字调用接受函数。这对于协议层没有影响,另外对于tcp套接字来说,无论数据是在等候接受还是即将抵达,都要重置连接(注意对于udp协议来说,仍然接受并排列传入的数据,因此udp套接字而言shutdown毫无意义)。如果选择SE_SEND,则表示不允许再调用发送函数。对于tcp套接字来说,这意味着会在所有数据发送出并得到接受端确认后产生一个FIN包。如果指定SD_BOTH,答案不言而喻。
closesocket:对此函数的调用会释放套接字的描述,这个道理众所周知(凡是经常翻阅msdn的程序员),因此,调用此函数后,再是用此套接字就会发生调用失败,通常返回的错误是WSAENOTSOCK。此时与被closesocket的套接字描述符相关联的资源都会被释放,包括丢弃传输队列中的数据!!!!对于当前进程中的线程来讲,所有被关起的操作,或者是被挂起的重叠操作以及与其关联的任何事件,完成例程或完成端口的执行都将调用失败!另外SO_LINGER标志还影响着closesocket的行为,但对于传统的socket程序,这里不加解释
因此可以可以看出shutdown对切断连接有着合理的完整性。 

二、从tcp协议上来分析shutdown和closesocket的行为(behavior):

closesocket或shutdown(使用SD_SEND当作参数时),会向通信对方发出一个fin包,而此时套接字的状态会由ESTABLISHED变成FIN_WAIT_1,然后对方发送一个ACK包作为回应,套接字又变成FIN_WAIT_2,如果对方也关闭了连接则对方会发出FIN,我方会回应一个ACK并将套接字置为TIME_WAIT。因此可以看出closesocket,shutdown所进行的TCP行为是一样的,所不同的是函数部分,shutdown会确保windows建立的数据传输队列中的数据不被丢失,而closesocket会冒然的抛弃所有的数据,因此如果你愿意closesocket完全可以取代shutdown,然而在数据交互十分复杂的网络协议程序中,最好还是shutdown稳妥一些!



close是关闭socket,彻底释放socket资源。 shutdown只是关闭掉socket中的某种行为(read/write),并不关闭socket。


凯里市18833364361: Socket 编程中 close() 和 shutdown() 有什么区别? -
原邦欣复: 一、指代不同1、shutdown() :是指禁止在一个套接口上进行数据的接收与发送.2、close():关闭一个套接口.更确切地说,它释放套接口描述字s,以后对s的访问均以WSAENOTSOCK错误返回.二、原理不同1、shutdown() :how参数...

凯里市18833364361: socket中shutdown和closesocket的区别 -
原邦欣复: 一、从函数调用上来分析(msdn):一旦完成了套接字的连接,应当将套接字关闭,并且释放其套接字句柄所占用的所有资源.真正释放一个已经打开的套接字句柄的资源直接调用closesocket即可,但要明白closesocket的调用可能会带来负面...

凯里市18833364361: socket shutdown和close的区别 -
原邦欣复: close(sockfd); 关闭socket,不管该socket上是否有没收万的数据,还是未发送的数据,强行关闭socket读和写.int shutdown(int sockfd,int how); 关闭socket ,但是要看第二个参数how 参数 how允许为shutdown操作选择以下几种方式: SHUT_...

凯里市18833364361: c调用 socket 如果客户端连接断开,怎么判断? 还有怎么向多个 连接在一个服务器上的多个客户 -
原邦欣复: 一: 如果客户端关闭连接,服务器端会收到一条连接关闭的消息,对应到你的C函数API就是,使用recv(或者read),读出的大小为0,此时就表明客户端断开连接了,如果是TCP的话,你也调用一次close(或者shutdown),这样就可以把一个TCP连接完美优雅的断开.二: 服务器编程肯定会在accept新连接之后,保存在一个数据结构中的.发送同样的内容,只需要遍历此数据结构即可.

凯里市18833364361: 怎样用C语言做socket网络编程? -
原邦欣复: mfc只是对socket进行了一些封装,大部分人做网络编程都是用的原始的socket,比如如下接口都可以在c下进行调用 1.socket()2.bind()3.connect()4.listen()5.accept()6.send() 和recv()7.sendto() 和recvfrom()8.close() 和shutdown()9.getpeername()10.gethostname() 这些接口是在Winsock2.h中定义的不是在mfc中定义的,你只需要包含Winsock2.h头文件和Ws2_32.lib库就可以了.

凯里市18833364361: 请教关于socket的close和shutdown问题 -
原邦欣复: 书中解释如下: socket.setSoLinger(true,3600); 执行Socket的close()方法,该方法不会立即返回,而进入阻塞状态.同时,底层的Socket会尝试发送剩余的数据.只有满足以下两个条件之一,close()方法才返回: 1、底层的Socket已经发送完所有的剩

凯里市18833364361: C# socket 如何断开连接 -
原邦欣复: Close只是通知底层socket关闭而已,并不一定保证底层的链接一定释放了,所以你一下子创建那么多链接肯定出问题备注Close 方法可关闭远程主机连接,并释放所有与 Socket 关联的托管资源和非托管资源.关闭后,Connected 属性将设置...

凯里市18833364361: 只shutdown不close socket连接会断开么 -
原邦欣复: int shutdown(SOCKET s, int how);函数:用于通知对方不再发送数据,或者不再接收数据,或者既不发送也不接收数据.int closesocket(SOCKET s);函数:关闭套接字,释放所占资源.从字面意思看shutdown不closesockt是不会断开连接的.

凯里市18833364361: shutdown()的简述 -
原邦欣复: 禁止在一个套接口上进行数据的接收与发送.Linux:#include int shutdown(int sockfd,int how); linux下成功则返回0,错误返回-1,错误码errno:EBADF表示sockfd不是一个有效描述符;ENOTCONN表示sockfd未连接;ENOTSOCK表示sockfd是一...

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网