找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 10098|回复: 9

socket recv 问题

[复制链接]
发表于 2010-4-27 18:10:41 | 显示全部楼层 |阅读模式
大家好:
     不知道大家在开发网络程序的过程有没有出现过这种问题:
        (1) tcp服务器部署在linux机器上.
     (2) 压力测试的过程中出现失败的情况, 查看服务器的套接字的状态. 看到一些close_wait状态.
     (3) 这时,我用简陋的测试客户端(windows socket)向服务器发数据. 跟踪发现.客户端connect成功.send也成功.客户端的recv会阻塞一会,返回返回-1, WSAGetLastError()时返回WSAECONNRESET. 但是服务器好像没有接收到客户端的这次连接(给人的感觉好你服务器进程死了).但此时服务器进程没crash. 监听端口的状态为LISTEN.

     另外:我没有修改linux下对进程打开的文件数的限制. 默认为1024.

    有经验的朋友,知道原因吗?
    谢谢.

   附:
   用tcpdump在服务器端的输出
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes
03:07:03.596489 IP localhost.mtportmon > localhost.8005: Flags [S], seq 1346912161, win 65535, options [mss 1460,nop,nop,sackOK], length 0
03:07:03.596545 IP localhost.8005 > localhost.mtportmon: Flags [S.], seq 2966971840, ack 1346912162, win 5840, options [mss 1460,nop,nop,sackOK], length 0
03:07:03.597111 IP localhost.mtportmon > localhost.8005: Flags [.], ack 1, win 65535, length 0
03:07:07.049852 IP localhost.mtportmon > localhost.8005: Flags [P.], ack 1, win 65535, length 78
03:07:09.914679 IP localhost.mtportmon > localhost.8005: Flags [P.], ack 1, win 65535, length 78
03:07:11.047173 IP localhost.8005 > localhost.mtportmon: Flags [S.], seq 2966971840, ack 1346912162, win 5840, options [mss 1460,nop,nop,sackOK], length 0
03:07:11.047997 IP localhost.mtportmon > localhost.8005: Flags [.], ack 1, win 65535, length 0
03:07:15.925132 IP localhost.mtportmon > localhost.8005: Flags [P.], ack 1, win 65535, length 78
03:07:22.814229 IP localhost.8005 > localhost.mtportmon: Flags [S.], seq 2966971840, ack 1346912162, win 5840, options [mss 1460,nop,nop,sackOK], length 0
03:07:22.815033 IP localhost.mtportmon > localhost.8005: Flags [.], ack 1, win 65535, length 0
03:07:27.946022 IP localhost.mtportmon > localhost.8005: Flags [P.], ack 1, win 65535, length 78
03:07:46.315183 IP localhost.8005 > localhost.mtportmon: Flags [S.], seq 2966971840, ack 1346912162, win 5840, options [mss 1460,nop,nop,sackOK], length 0
03:07:46.316047 IP localhost.mtportmon > localhost.8005: Flags [.], ack 1, win 65535, length 0
03:07:51.878459 IP localhost.mtportmon > localhost.8005: Flags [P.], ack 1, win 65535, length 78
03:08:21.930662 IP localhost.mtportmon > localhost.8005: Flags [P.], ack 1, win 65535, length 78
03:08:33.793200 IP localhost.8005 > localhost.mtportmon: Flags [S.], seq 2966971840, ack 1346912162, win 5840, options [mss 1460,nop,nop,sackOK], length 0
03:08:33.794037 IP localhost.mtportmon > localhost.8005: Flags [.], ack 1, win 65535, length 0
03:10:07.713080 IP localhost.8005 > localhost.mtportmon: Flags [S.], seq 2966971840, ack 1346912162, win 5840, options [mss 1460,nop,nop,sackOK], length 0
03:10:07.713957 IP localhost.mtportmon > localhost.8005: Flags [R], seq 1346912162, win 0, length 0

[ 本帖最后由 sugar 于 2010-4-27 19:18 编辑 ]
 楼主| 发表于 2010-4-28 09:49:08 | 显示全部楼层
根据tcpdump的输出,发现三次握手已经完成, 可能是服务器的应用层因为套接字句柄数的限制,而没有创建连接套接字, 我用的是ACE_TP_Reactor,linux环境下.  FD_SETSIZE好像是1024. 压力测试下,大量的close_wait状态使得无法创建套接字. 也想换成poll. 但是太多的close_wait也会将可打开的文件句柄数消耗完.  走查代码,也处理了对端关闭的情况.难道只能设置SO_LINGER来处理吗?   对于一个高性能的服务器(非多进程模式下)大伙都是如何来处理close_wait的?

[ 本帖最后由 sugar 于 2010-4-28 13:20 编辑 ]
发表于 2010-4-28 10:25:15 | 显示全部楼层
推荐使用DDEV_POLL。
通过ulimit -a 查看你的IO限制,并修改这个限制,查询一下以往的帖子,有这方面设置的帖子。
不知道你测试了多少个客户端链接?
另外close_wait说明你的TCP链接已经关闭,进入等待系统清除状态。
这里推荐你一片文章。
http://hi.baidu.com/jiaskyboy/bl ... 0dbd23c65cc39f.html
 楼主| 发表于 2010-4-28 11:06:38 | 显示全部楼层

回复 #3 freeeyes 的帖子

freeeyes 你好,
我注意到你的建议. 我现在的问题不是在ACE_Dev_Poll_Reactor或是linux对一个进程可打开的句柄数限制.(如果大量套接字处于close_wait状态,无论多大的句柄数都将被消耗完)
我使用loadRuner进行压力测试,大量的并发请求使用服务器非常繁忙.
问题在于: 我发现服务器端有大量的套接字处于close_wait状态. 并且一直处理于这个状态.而不会变成LAST_ACK.这说明客户端向服务器发送了FIN,服务器回就了ack,但是并没有向客户端发送FIN. (当然测试脚本程序也许有问题.但一个健壮的服务器必须处理这种类似的异常情况). 服务器在检测客户断开时,因为异常没有close或者close调用失败(而我没有处理这种异常).导致没有发送最后一个FIN. 难道一定要通过设置SO_LINGER吗? unxi网络编程卷一 也有提到有些应用通过设置些选项来处理close_wait状态(大概在P180-P200之间).

[ 本帖最后由 sugar 于 2010-4-28 11:11 编辑 ]
发表于 2010-4-28 12:40:29 | 显示全部楼层
“没有修改linux下对进程打开的文件数的限制. 默认为1024”
改大些很麻烦么?你的需求是 高性能服务器 啊
发表于 2010-4-28 13:09:33 | 显示全部楼层
文件句柄数量,是个重要的环节。因为UNIX的理念是“一切皆为文件”,句柄限制住了,等于系统捆住了手脚。
 楼主| 发表于 2010-4-28 13:15:39 | 显示全部楼层

回复 #5 wishel 的帖子

这些限制都会修改的.

问题变成了: 实际工作中大家是如何处理close_wait状态的.
 楼主| 发表于 2010-4-28 13:36:52 | 显示全部楼层
找到一篇文章有介绍: 主要观点是从程序上关闭这个套接字.
http://www.sunmanagers.org/pipermail/summaries/2006-January/007068.html
发表于 2010-4-28 14:28:50 | 显示全部楼层
楼主可以参考一下这个帖子

http://www.acejoy.com/bbs/viewth ... &extra=page%3D1
 楼主| 发表于 2010-4-28 14:57:49 | 显示全部楼层

回复 #9 wishel 的帖子

谢谢wishel.
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

Archiver|手机版|小黑屋|ACE Developer ( 京ICP备06055248号 )

GMT+8, 2024-12-22 15:54 , Processed in 0.024792 second(s), 7 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表