中国开发网: 论坛: 程序员情感CBD: 贴子 76616
haitao
网上捜到的解决办法
这个说得很好,但该怎么作呢?

7、 socket问题
我有一服务器solaris7,端口20007提供一个高级服务。可是经常会出现拒绝服务现象:

10.2.20.42.20007 10.2.20.104.2805 32120 0 10136 0 CLOSE_WAIT
10.2.20.42.20007 10.21.104.241.50629 5840 0 9716 0 CLOSE_WAIT

如果正常情况下不会有close_wait状态的连接。
我想是否有控制socket等待时间大小的变量?谁告诉我?
因为一旦socket连接断开后--对方原因,本地的socket并没有立即回收而是处于close_wait状态,等待很长时间后会变成time_wait状态,然后才回收。。

这是一个tcp/ip实现上的问题,除非你修改你的协议,wait状态的存在是有他的道理的;而且那不会影响到新的连接;
拒绝服务可能是因为并发连接数超过了listen中backlog造成的;当内核接受到的连接请求充满内核的请求队列的时候,新的连接请求就会被拒绝;
写程序,经常也碰见这种情况,主要是有一方关闭SOCKET,但是另外一方没有检测到,导致没有检测到的一方出现CLOSE_WAIT的情况。



大富翁的很奇怪:似乎没人回答

关于TCP编程中close_wait状态的问题? ( 积分:100, 回复:3, 阅读:155 )
分类:Internet/TCPIP ( 版主:luyear, robertcool )
来自:yeath, 时间:2004-2-4 14:28:00, ID:2435662 [显示:小字体 | 大字体]

各位高手:我用C++ Builder中的Socket控件写了一个服务端,客户端是在Linux上用C开发的,为什么运行一段时间后,在服务端上用Netstat查看,出现很多close_wait状态的连接,并且产生拒绝服务的现象,导致客户端无法连接。请问如何解决。。。


来自:LeeChange, 时间:2004-3-1 16:07:49, ID:2478568
close_wait是TCP连接被被动关闭时的一种状态。
Socket从对方接收到一个FIN包,就会返回一个ACK包做回应,并将自己的状态调整为close_wait。


来自:yeath, 时间:2004-3-1 17:14:29, ID:2478791
那如何才能避免拒绝服务呢?


来自:yeath, 时间:2004-5-28 19:02:51, ID:2633383
接受答案了.




这个好像没到点上:【

通常在进行多线程创建短连接做压力测试的时候由于一方或另一方非正常退出程序(比如ctrl+c)
就会出现close_wait状态,此时再重新创建连接经常无法成功,一般该如何解决?


无双 2004-12-25 13:04:58 Post #2


天才猪


组别: 管理员
发贴数量: 4219


注册时间: 2003-09-16
来自: 杭州
用户编号: 4



试试setsockopt SO_LINGER 看


--------------------

无双客栈


orian 2004-12-25 15:39:28 Post #3


御武副尉


组别: 技术专家
发贴数量: 716


注册时间: 2004-04-14
用户编号: 18050



增加/etc/security/limits里的 files,可以考虑改成-1,可能需要重新启动


--------------------

垃圾猪 Orian

下岗进行中......
看.看..看成败,大...大不了从.从.阿就从头再来

email & msn ensighine@yahoo.com


无双 2004-12-25 19:07:07 Post #4


天才猪


组别: 管理员
发贴数量: 4219


注册时间: 2003-09-16
来自: 杭州
用户编号: 4



orian的建议不错

rlimit好像也可以修改可用的文件数目

不过如果一直不close 那应该不是个办法

这个帖子已被 无双 于 2004-12-26 14:22:32 编辑


--------------------

无双客栈


燕然 2004-12-27 09:03:50 Post #5


陪戎副尉


组别: 会员
发贴数量: 54


注册时间: 2003-10-22
用户编号: 885



我一般是在bind之前,使用setsockopt SO_REUSEADDR



无双 2004-12-27 12:25:19 Post #6


天才猪


组别: 管理员
发贴数量: 4219


注册时间: 2003-09-16
来自: 杭州
用户编号: 4



进程关闭时 它的所有打开的文件句柄都会关闭

所以当对方程序退出时

socket是会关闭的


--------------------

无双客栈


燕然 2004-12-28 09:05:28 Post #7


陪戎副尉


组别: 会员
发贴数量: 54


注册时间: 2003-10-22
用户编号: 885



好像不是这样吧
比如:如果设置了linger为off,那么调用者直接返回了,但是关闭操作要延后呀



燕然 2004-12-28 09:08:38 Post #8


陪戎副尉


组别: 会员
发贴数量: 54


注册时间: 2003-10-22
用户编号: 885



进程关闭时 它的所有打开的文件句柄都会关闭
所以当对方程序退出时
socket是会关闭的

对不起上面的问题是我看错了,虽然文件没有被系统关闭
但是进程内的文件句柄被关闭应该没有问题,
这个进程这时不会对文件进行存取控制了。



这个似乎没给出解决办法:【
怎样快速清除close_wait状态的套接字?



用netstat常发现很多连接处于close_wait状态,有没有方法迅速清除系统上的这些连接?
谢谢!

文章选项:

songs
(member)
08/11/04 12:23
Re: 怎样快速清除close_wait状态的套接字? [re: hnxxld]



from "securing-optimizing-linux-the-ultimate-solution-v2.0" p183:

Edit the sysctl.conf file (vi /etc/sysctl.conf) and add the following lines:
# Decrease the time default value for tcp_fin_timeout connection
net.ipv4.tcp_fin_timeout = 30
# Decrease the time default value for tcp_keepalive_time connection
net.ipv4.tcp_keepalive_time = 1800
# Turn off the tcp_window_scaling support
net.ipv4.tcp_window_scaling = 0
# Turn off the tcp_sack support
net.ipv4.tcp_sack = 0
# Turn off the tcp_timestamps support
net.ipv4.tcp_timestamps = 0

你试试看是不是有效...

文章选项:

dl_dht
(addict)
08/11/04 15:13
Re: 怎样快速清除close_wait状态的套接字? [re: hnxxld]



I think this case is what you wanted or this is a bug of your program , when your tcp peer program close the socket , your program receive FIN and from ESTABLISHED to CLOSE_WAIT, at this time if your program doesn't want to send any data too, it should close sockfd, and from CLOSE_WAIT to LAST_ACK. or it will stay in CLOSE_WAIT state.



试过下面的设置,但是无效:


  /*
   * 一旦套接口被建立,它的运作机制可以通过套接口选项(socket option)进行修改。   
   */

  /*
   * SO_REUSEADDR选项的设置将套接口设置成重新使用旧的地址(IP地址加端口号)而不等待
   * 注意:在Linux系统中,如果一个socket绑定了某个端口,该socket正常关闭或程序退出后,
   * 在一段时间内该端口依然保持被绑定的状态,其他程序(或者重新启动 的原程序)无法绑定该端口。
   *
   * 下面的调用中:SOL_SOCKET代表对SOCKET层进行操作
   */
  on = 1;

  status = setsockopt(serverSocket, SOL_SOCKET,
SO_REUSEADDR,
    (const char *) &on, sizeof(on));

  if (-1 == status)
  {
    perror("setsockopt(...,SO_REUSEADDR,...)");
  }

  /* 当连接中断时,需要延迟关闭(linger)以保证所有数据都
   * 被传输,所以需要打开SO_LINGER这个选项
   * linger的结构在/usr/include/linux/socket.h中定义:
   *  struct linger
   *  {
   *   int l_onoff;  /* Linger active */
   *   int l_linger; /* How long to linger */
   *  };


  *  如果l_onoff为0,则延迟关闭特性就被取消。如果非零,则允许套接口延迟关闭。
   *  l_linger字段则指明延迟关闭的时间
   */


  {
    struct linger linger = { 0 };

    linger.l_onoff = 1;
    linger.l_linger = 30;
    status = setsockopt(serverSocket,
SOL_SOCKET, SO_LINGER,
(const char *) &linger,
sizeof(linger));

    if (-1 == status)
    {
      perror("setsockopt(...,SO_LINGER,...)");
    }
  }


我的blog:http://szhaitao.blog.hexun.com & http://www.hoolee.com/user/haitao
--以上均为泛泛之谈--
不尽牛人滚滚来,无边硬伤纷纷现 人在江湖(出来的),哪能不挨刀(总归是要的)
网络对话,歧义纷生;你以为明白了对方的话,其实呢?

您所在的IP暂时不能使用低版本的QQ,请到:http://im.qq.com/下载安装最新版的QQ,感谢您对QQ的支持和使用

相关信息:


欢迎光临本社区,您还没有登录,不能发贴子。请在 这里登录