socket关闭后为什么recv不返回

edifier 2010-11-07 01:18:48
程序中实现客户端和服务器端功能,socket均使用阻塞方式接收和发送。客户端主动关闭本次socket,recv立即从阻塞方式返回。而在服务器端,socket由accept获得,参数均设置成和客户端socket一样,程序运行时,服务器端自动关闭socket,程序仍阻塞在recv函数中,请各位大拿帮忙分析一下是什么问题,同样的程序在win32下正常。
...全文
1194 14 打赏 收藏 举报
写回复
14 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
edifier 2010-11-14
  • 打赏
  • 举报
回复
6楼正解,服务器端主动断开与客户端连接时,先shutdown,再close,服务器端代码可以很快从recv阻塞中返回。3ks。
lazy_2010 2010-11-12
  • 打赏
  • 举报
回复
在 recv 之前,没有调用 select 函数?
gettext 2010-11-11
  • 打赏
  • 举报
回复
tcp socket关闭是单向的, client recv出错后需要close socket.
edifier 2010-11-11
  • 打赏
  • 举报
回复
大家的理解有偏差,是我没说清楚。代码是公共代码,既可以用于服务器,也可以用于客户端。
当作为客户端运行时,不管是对侧(服务器端)发起关闭,还是本侧(客户端)主动关闭与服务器的连接,客户端程序均能很快从recv阻塞状态中返回。
当作为服务器运行时,对侧(客户端)发起关闭,服务器应用程序可以很快从recv阻塞状态返回,但服务器主动关闭与客户端的连接时则服务器程序一直阻塞在recv函数中。
hawk198 2010-11-11
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 gettext 的回复:]

tcp socket关闭是单向的, client recv出错后需要close socket.
[/Quote]
就是这个情况,如果服务器close了,客户端的阻塞就结束了,收到0,表示是对端关闭,这时候客户端需要处理的
justkk 2010-11-09
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 edifier 的回复:]
可能没写清楚:当作为客户端运行时,不管是对侧(服务器端),还是本侧主动关闭,客户端程序均能很快从recv阻塞状态中返回。
当作为服务器运行时,对侧(客户端)关闭,服务器应用程序可以很快从recv阻塞状态返回,但服务器主动关闭该连接时则服务器程序一直阻塞在recv函数中。
[/Quote]
还是没听明白..
客户端运行时,本侧关闭??客户端关闭自己的描述符?
谭海燕 2010-11-09
  • 打赏
  • 举报
回复
server主动close掉connect,server会通知client,client会做出应答,
然后client会发起close。


参考这个帖子,跟你差不多的问题

http://topic.csdn.net/u/20100914/19/6ff94f36-9ef7-420f-9764-613e53c2c0f3.html?88453
yangzhifu 2010-11-09
  • 打赏
  • 举报
回复
遇到过这样的问题,客户端断开后服务端可以很好的检测,但是相反服务端断开后客户端一只阻塞读,其原因在于你在服务端调用的是close,而不是shutdown函数;因为close只有在最后一个获得引用被关闭时菜释放网络端点,如果你的服务端套接字被复制了(dup),那么它将不会被关闭;相反shutdown函数可以使一个套接字处于不活动状态,无论它的引用文件描述符是多少;所以建议你在服务器端采用shutdown函数。


这些东西在《unix环境高级编程》439页有详细讲述。
wbruce 2010-11-09
  • 打赏
  • 举报
回复
感觉逻辑有问题,recv的返回应该是有对方close描述符发起的吧,所谓的四次挥手先由对方发起,本端recv返回0
edifier 2010-11-07
  • 打赏
  • 举报
回复
可能没写清楚:当作为客户端运行时,不管是对侧(服务器端),还是本侧主动关闭,客户端程序均能很快从recv阻塞状态中返回。
当作为服务器运行时,对侧(客户端)关闭,服务器应用程序可以很快从recv阻塞状态返回,但服务器主动关闭该连接时则服务器程序一直阻塞在recv函数中。
edifier 2010-11-07
  • 打赏
  • 举报
回复
代码较多,无法贴出,socket设置了以下属性:
SO_LINGER:启用
SO_RCVTIMEO:0s,无延时
TCP_NODELAY:启用
SO_SNDTIMEO:2s
SO_KEEPALIVE:打开
唯一的区别,客户端的socket是由socket()建立的,服务器端的socket是由accept()返回的。正常通信之后,需要主动断开时,close()本侧的socket,客户端可以从recv()阻塞中立即返回,而服务器端主动关闭时则程序一直阻塞在recv函数中。该部分代码在win32、vxworks下均正常。
Xjbala 2010-11-07
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 weifirst118 的回复:]
贴代码上来
[/Quote]
up!
weifirst118 2010-11-07
  • 打赏
  • 举报
回复
贴代码上来
mymtom 2010-11-07
  • 打赏
  • 举报
回复
对方关闭了主动关闭时, recv/read都会返回0啊。
相关推荐
发帖
Linux/Unix社区

2.2w+

社区成员

Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
帖子事件
创建了帖子
2010-11-07 01:18
社区公告
暂无公告