199 c sockets networking
在C中,我理解如果我们关闭套接字,则意味着套接字将被销毁,以后可以重新使用.
关机怎么样?描述说它关闭了与该套接字的双工连接的一半.但是那个套接字会像close系统调用一样被销毁吗?
Mat*_*hen 179
这在Beej的网络指南中有解释. shutdown是一种在一个或两个方向上阻止通信的灵活方式.当第二个参数是时SHUT_RDWR,它将阻止发送和接收(如close).但是,close是实际销毁套接字的方法.
有了shutdown,您仍然可以接收同伴已经发送的待处理数据(感谢Joey Adams注意到这一点).
Ear*_*ine 122
现有的答案都不告诉人们如何shutdown以及close在TCP协议级别的作品,所以它是值得添加此.
标准TCP连接通过4路终结终止:
但是,还有另一种"紧急"方式来关闭TCP连接:
在我使用Wireshark进行的测试中,使用默认套接字选项,shutdown将FIN数据包发送到另一端,但就是这样.在另一方向您发送FIN数据包之前,您仍然可以接收数据.一旦发生这种情况,您Receive将获得0大小的结果.因此,如果您是第一个关闭"发送"的人,则应在完成数据接收后关闭套接字.
另一方面,如果close在连接仍处于活动状态时进行呼叫(另一端仍然处于活动状态,并且系统缓冲区中可能还有未发送的数据),则会将RST数据包发送到另一端.这有利于错误.例如,如果您认为对方提供了错误的数据或拒绝提供数据(DOS攻击?),您可以立即关闭套接字.
我对规则的看法是:
shutdown之前close可能当SHUT_RD和SHUT_WR的理想实现
以下未经过测试,信任风险自负.但是,我相信这是一种合理而实用的做事方式.
如果TCP堆栈仅通过SHUT_RD接收关闭,则应将此连接标记为不再需要数据.任何挂起和后续read请求(无论它们处于哪个线程)都将返回零大小的结果.但是,连接仍然是活动的和可用的 - 例如,您仍然可以接收OOB数据.此外,操作系统将删除它为此连接接收的任何数据.但就是这样,没有包裹会被发送到另一方.
如果TCP堆栈仅通过SHUT_WR接收关闭,则应标记此连接,因为不能再发送数据.所有挂起的写入请求都将完成,但后续写入请求将失败.此外,FIN数据包将被发送到另一侧以通知他们我们没有更多数据要发送.
Mil*_*lan 35
close()如果使用shutdown()相反的话,可以避免一些限制.
close()将终止TCP连接上的两个方向.有时您想告诉另一个端点您已完成发送数据,但仍希望接收数据.
close()递减描述符引用计数(在文件表条目中维护并计算当前打开的引用文件/套接字的描述符的数量),如果描述符不为0则不关闭套接字/文件.这意味着如果要分配,只有在引用计数降为0后才会进行清理.shutdown()一个可以启动正常的TCP关闭序列,忽略引用计数.
参数如下:
int shutdown(int s, int how); // s is socket descriptor
Run Code Online (Sandbox Code Playgroud)
int how 可:
SHUT_RD或0
进一步接收是不允许的
SHUT_WR或者1
不允许进一步发送
SHUT_RDWR或者2
不允许进一步发送和接收
Len*_*ate 15
这可能是平台特定的,我不知何故怀疑它,但无论如何,我见过的最好的解释是在这个msdn页面上,他们解释了关闭,延迟选项,套接字闭包和一般连接终止序列.
总之,使用shutdown在TCP级别发送关闭序列,并使用close来释放进程中套接字数据结构使用的资源.如果在调用close时没有发出明确的关闭序列,则会启动一个关闭序列.
我也在Linux下使用shutdown()一个pthread成功强制另一个当前被阻止的pthread connect()提前中止.
在其他操作系统(至少OSX)下,我发现调用close()足以connect()导致失败.
| 归档时间: |
|
| 查看次数: |
228936 次 |
| 最近记录: |