免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 24593635 | 回复: 24593635
打印 上一主题 下一主题

断开的TCP连接为什么还存在ESTABLISHED? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2005-11-05 22:07 |只看该作者 |倒序浏览
最近在linux下写了个http代理程序,代理是通过多线程实现的,后来进行压力测试后发现,客户端已经断开了所有的连接,但是在代理的机器上用netstat还能看到ESTABLISHED状态的连接存在,而且一些子线程也没有正常退出,一直存在,网络状态也一直是ESTABLISHED,请大家帮忙分析一下原因,谢谢了

论坛徽章:
0
2 [报告]
发表于 2005-11-06 03:21 |只看该作者
服务端close了吗

论坛徽章:
0
3 [报告]
发表于 2005-11-06 09:38 |只看该作者
我也遇到过一样的问题,不过问题时解决了,但是不清楚为什么会这样?

http://bbs.chinaunix.net/viewthr ... ge=1&highlight=

论坛徽章:
0
4 [报告]
发表于 2005-11-06 13:11 |只看该作者
这个现象是正常的吧?如果Client死机的话Server不会知道的。Client重新开机后连接依然存在,仍然能正常通讯。如果是服务器死掉重新开机后,Client向Server发送数据,则服务器回应一个FIN断开连接。
我觉得定时在Server和Client之间发送心跳检测数据可以解决问题。

论坛徽章:
0
5 [报告]
发表于 2005-11-06 14:38 |只看该作者
后遗症?

论坛徽章:
0
6 [报告]
发表于 2005-11-06 15:38 |只看该作者

回复 3楼 xiaofei104 的帖子

能说说是如何解决的吗?这个问题我一直很头疼

论坛徽章:
0
7 [报告]
发表于 2005-11-06 15:44 |只看该作者
原帖由 yhch 于 2005-11-6 13:11 发表
这个现象是正常的吧?如果Client死机的话Server不会知道的。Client重新开机后连接依然存在,仍然能正常通讯。如果是服务器死掉重新开机后,Client向Server发送数据,则服务器回应一个FIN断开连接。
我觉得定时在 ...

client端是运行一段时间后停止的,按理说,我的代理程序是使用select对recv进行超时限制的,那为什么我用gdb对那么没有停止的线程进行调试时,提示是在sock_read函数中?

论坛徽章:
0
8 [报告]
发表于 2005-11-06 15:52 |只看该作者
贴上GDB的信息:
(gdb) where
#0  0x420daca4 in read () from /lib/i686/libc.so.6
#1  0x402b7b18 in __libc_internal_tsd_get () from /lib/i686/libpthread.so.0
#2  0x0809a87e in sock_read ()
#3  0x08360ed8 in ?? ()
(gdb)

论坛徽章:
0
9 [报告]
发表于 2005-11-06 18:58 |只看该作者
原帖由 yhch 于 2005-11-6 13:11 发表
这个现象是正常的吧?如果Client死机的话Server不会知道的。Client重新开机后连接依然存在,仍然能正常通讯。如果是服务器死掉重新开机后,Client向Server发送数据,则服务器回应一个FIN断开连接。
我觉得定时在 ...


你的说法肯定是不正确的。

1。在正常情况下是不会出现这个问题的。你可以自己写一个简单的Client/Server程序试试,Client断了,服务器端一定可以知道。因为你的服务器端一直在等待客户端的数据。

2.这个问题在有多线程的时候可能比较容易出现。

To:楼主:

1。因为我的Client/Server都是自己写的。所以我的做法是在Client中加了一个钩子去显示的close掉socket.而不是依赖于进程的关闭时候的资源释放。

2。你的情况可以试试将线程设置为守护线程,将socket资源设置为线程内的一个变量,而非一个全局的,在多个线程间共享的。

论坛徽章:
0
10 [报告]
发表于 2005-11-07 09:10 |只看该作者
原帖由 xiaofei104 于 2005-11-6 18:58 发表

1。因为我的Client/Server都是自己写的。所以我的做法是在Client中加了一个钩子去显示的close掉socket.而不是依赖于进程的关闭时候的资源释放。

2。你的情况可以试试将线程设置为守护线程,将socket资源设置为线程内的一个变量,而非一个全局的,在多个线程间共享的。


1."client是否close"和"server上的连接显示established"是没有关系的
  就像你说的,连接断了,server是肯定知道的,因为select()的返回是可读,read()的返回是0

2.这个完全没有必要吧,每个处理连接的线程在知道自己所对应的连接断开后,自己可以先close了再退出

我觉得LZ的问题可能在于server对连接的处理流程,你的server是否时刻在监控着这个连接?
比如每个线程的处理可以大体是这样的

  1. while(1)
  2. {
  3.     pthread_testcancel();
  4.        
  5.     if(select(..))  //sleep()可以在这里实现
  6.     {
  7.         int ret = read(...);
  8.                
  9.         if(ret < 0)  //read()出错
  10.         {
  11.             //
  12.             close(sockfd);
  13.             pthread_exit();           
  14.         }
  15.         else if (ret == 0)  //连接断开
  16.         {
  17.             //
  18.             close(sockfd);
  19.             pthread_exit();         
  20.         }
  21.         else  //正确
  22.         {
  23.             //
  24.         }
  25.     }
  26. }
复制代码

[ 本帖最后由 xujg 于 2005-11-7 09:14 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP