程序跑一段时间以后,端口还处在LISTENING状态,但是本地Telnet都不通

时间:2022-01-30 02:04:46

程序刚开始还运行正常,若干天后,突然发现连不上了,登录到服务器一看,发现本地telnet服务器端口都不通,用netstat查看,端口处于LISTENING状态,怀疑是防火墙原因,把防火墙关掉,问题依旧,抓包看,服务器对TCP三次握手报文根本无反应,服务器其他端口没问题,见了鬼了,有谁遇到过这种问题?我现在怀疑是系统出了什么问题,大家有什么好的思路吗?

14 个解决方案

#1


定时检查socket状态,若不是LISTENING,重新调用listen

#2


检查是否资源泄漏的办法之一:
在任务管理器 进程 查看 选择列 里面选择:内存使用、虚拟内存大小、句柄数、线程数、USER对象、GDI对象
让你的程序(进程)不退出,循环执行主流程很多遍,越多越好,比如1000000次甚至无限循环,记录以上各数值,再隔至少一小时,越长越好,比如一个月,再记录以上各数值。如果以上两组数值的差较大或随时间流逝不断增加,则铁定有对应资源的资源泄漏!

#3


netstat -na | find "WAIT"

#4


多半是进程在bind,listen在其他地方阻塞住了,没有 accpet

#5


引用 4 楼 mujiok2003 的回复:
多半是进程在bind,listen在其他地方阻塞住了,没有 accpet

accept

#6


引用 4 楼 mujiok2003 的回复:
多半是进程在bind,listen在其他地方阻塞住了,没有 accpet


忘了说明,是一个服务器程序,刚开始运行时正常的,可以正常提供服务,运行一段时间才有这个问题。

另外,抓包看了,服务器对三次握手报文根本无响应,在本机测试也是这样,我测试过,就算没有accept,telnet也是能通的。

所以,我怀疑系统协议栈那一层的处理已经有问题,至于问题是由于服务器程序导致的,还是其他问题导致的,没有什么思路往下查。

#7


就是服务器没accept

你出问题后把你的服务器程序关了,用nc监听那个端口试试能不能telnet

#8


引用 7 楼 q191201771 的回复:
就是服务器没accept

你出问题后把你的服务器程序关了,用nc监听那个端口试试能不能telnet


我理解,三次握手是由操作系统完成的,现在不敢关闭或重启程序,这种问题很难出现。

我测试过,不管是在linux还是windows,三次握手只要listen就足够了,不需要accept。

#9


这种问题是你没处理好socket关闭,而且可以确认的是你有很多socket处于TIMW_WAIT状态。可以看出来,是你服务器主动关闭socket,但是你的client没有处理socket关闭或者因为其他原因没有关闭。这时候服务器的socket会有60-120分钟处于TIME_WAIT状态(一般机器的默认设置),所以时间一长你就不能连接了。

解决方法有很多,一是设置服务器的默认时间,二是修改socket属性。具体怎么设置你自己搜下吧。

PS:再认真学习下TCP状态转移图吧,对你理解这些会很有帮助。

#10


这个问题要详细了说,监听端口是有队列的,如果你程序不accept,那个队列会满的

还一个可能是你服务器进程的文件描述符用尽了
你如果没设置ulimit可以查一下你系统内核设置的限制是多少
ulimit -n
再netstat查查那个端口的情况
netstat -anp | grep :80

#11


引用 10 楼 q191201771 的回复:
这个问题要详细了说,监听端口是有队列的,如果你程序不accept,那个队列会满的

还一个可能是你服务器进程的文件描述符用尽了
你如果没设置ulimit可以查一下你系统内核设置的限制是多少
ulimit -n
再netstat查查那个端口的情况
netstat -anp | grep :80


分析的有道理,的确如您所说,是accept队列满导致,但是为什么accept队列会满,暂时没有找到原因。
不过,已经可以做一些补救措施,出现这种问题时,重新创建监听,暂时可以规避此问题。

#12


引用 2 楼 zhao4zhong1 的回复:
检查是否资源泄漏的办法之一:
在任务管理器 进程 查看 选择列 里面选择:内存使用、虚拟内存大小、句柄数、线程数、USER对象、GDI对象
让你的程序(进程)不退出,循环执行主流程很多遍,越多越好,比如1000000次甚至无限循环,记录以上各数值,再隔至少一小时,越长越好,比如一个月,再记录以上各数值。如果以上两组数值的差较大或随时间流逝不断增加,则铁定有对应资源的资源泄漏!


大哥,根据你的提示,我发现了一个问题。你提的这些,怎么查询,命令能否贴一下?

#13


引用 12 楼 lijunwyf 的回复:
Quote: 引用 2 楼 zhao4zhong1 的回复:

检查是否资源泄漏的办法之一:
在任务管理器 进程 查看 选择列 里面选择:内存使用、虚拟内存大小、句柄数、线程数、USER对象、GDI对象
让你的程序(进程)不退出,循环执行主流程很多遍,越多越好,比如1000000次甚至无限循环,记录以上各数值,再隔至少一小时,越长越好,比如一个月,再记录以上各数值。如果以上两组数值的差较大或随时间流逝不断增加,则铁定有对应资源的资源泄漏!


大哥,根据你的提示,我发现了一个问题。你提的这些,怎么查询,命令能否贴一下?

在MSDN里面搜“PDH”?

#14


分析的有道理,的确如您所说,是accept队列满导致,但是为什么accept队列会满,暂时没有找到原因。
 不过,已经可以做一些补救措施,出现这种问题时,重新创建监听,暂时可以规避此问题。



楼主,我也遇到跟您一样的问题,重新创建监听,应该怎么做呢?请贴出操作。

#1


定时检查socket状态,若不是LISTENING,重新调用listen

#2


检查是否资源泄漏的办法之一:
在任务管理器 进程 查看 选择列 里面选择:内存使用、虚拟内存大小、句柄数、线程数、USER对象、GDI对象
让你的程序(进程)不退出,循环执行主流程很多遍,越多越好,比如1000000次甚至无限循环,记录以上各数值,再隔至少一小时,越长越好,比如一个月,再记录以上各数值。如果以上两组数值的差较大或随时间流逝不断增加,则铁定有对应资源的资源泄漏!

#3


netstat -na | find "WAIT"

#4


多半是进程在bind,listen在其他地方阻塞住了,没有 accpet

#5


引用 4 楼 mujiok2003 的回复:
多半是进程在bind,listen在其他地方阻塞住了,没有 accpet

accept

#6


引用 4 楼 mujiok2003 的回复:
多半是进程在bind,listen在其他地方阻塞住了,没有 accpet


忘了说明,是一个服务器程序,刚开始运行时正常的,可以正常提供服务,运行一段时间才有这个问题。

另外,抓包看了,服务器对三次握手报文根本无响应,在本机测试也是这样,我测试过,就算没有accept,telnet也是能通的。

所以,我怀疑系统协议栈那一层的处理已经有问题,至于问题是由于服务器程序导致的,还是其他问题导致的,没有什么思路往下查。

#7


就是服务器没accept

你出问题后把你的服务器程序关了,用nc监听那个端口试试能不能telnet

#8


引用 7 楼 q191201771 的回复:
就是服务器没accept

你出问题后把你的服务器程序关了,用nc监听那个端口试试能不能telnet


我理解,三次握手是由操作系统完成的,现在不敢关闭或重启程序,这种问题很难出现。

我测试过,不管是在linux还是windows,三次握手只要listen就足够了,不需要accept。

#9


这种问题是你没处理好socket关闭,而且可以确认的是你有很多socket处于TIMW_WAIT状态。可以看出来,是你服务器主动关闭socket,但是你的client没有处理socket关闭或者因为其他原因没有关闭。这时候服务器的socket会有60-120分钟处于TIME_WAIT状态(一般机器的默认设置),所以时间一长你就不能连接了。

解决方法有很多,一是设置服务器的默认时间,二是修改socket属性。具体怎么设置你自己搜下吧。

PS:再认真学习下TCP状态转移图吧,对你理解这些会很有帮助。

#10


这个问题要详细了说,监听端口是有队列的,如果你程序不accept,那个队列会满的

还一个可能是你服务器进程的文件描述符用尽了
你如果没设置ulimit可以查一下你系统内核设置的限制是多少
ulimit -n
再netstat查查那个端口的情况
netstat -anp | grep :80

#11


引用 10 楼 q191201771 的回复:
这个问题要详细了说,监听端口是有队列的,如果你程序不accept,那个队列会满的

还一个可能是你服务器进程的文件描述符用尽了
你如果没设置ulimit可以查一下你系统内核设置的限制是多少
ulimit -n
再netstat查查那个端口的情况
netstat -anp | grep :80


分析的有道理,的确如您所说,是accept队列满导致,但是为什么accept队列会满,暂时没有找到原因。
不过,已经可以做一些补救措施,出现这种问题时,重新创建监听,暂时可以规避此问题。

#12


引用 2 楼 zhao4zhong1 的回复:
检查是否资源泄漏的办法之一:
在任务管理器 进程 查看 选择列 里面选择:内存使用、虚拟内存大小、句柄数、线程数、USER对象、GDI对象
让你的程序(进程)不退出,循环执行主流程很多遍,越多越好,比如1000000次甚至无限循环,记录以上各数值,再隔至少一小时,越长越好,比如一个月,再记录以上各数值。如果以上两组数值的差较大或随时间流逝不断增加,则铁定有对应资源的资源泄漏!


大哥,根据你的提示,我发现了一个问题。你提的这些,怎么查询,命令能否贴一下?

#13


引用 12 楼 lijunwyf 的回复:
Quote: 引用 2 楼 zhao4zhong1 的回复:

检查是否资源泄漏的办法之一:
在任务管理器 进程 查看 选择列 里面选择:内存使用、虚拟内存大小、句柄数、线程数、USER对象、GDI对象
让你的程序(进程)不退出,循环执行主流程很多遍,越多越好,比如1000000次甚至无限循环,记录以上各数值,再隔至少一小时,越长越好,比如一个月,再记录以上各数值。如果以上两组数值的差较大或随时间流逝不断增加,则铁定有对应资源的资源泄漏!


大哥,根据你的提示,我发现了一个问题。你提的这些,怎么查询,命令能否贴一下?

在MSDN里面搜“PDH”?

#14


分析的有道理,的确如您所说,是accept队列满导致,但是为什么accept队列会满,暂时没有找到原因。
 不过,已经可以做一些补救措施,出现这种问题时,重新创建监听,暂时可以规避此问题。



楼主,我也遇到跟您一样的问题,重新创建监听,应该怎么做呢?请贴出操作。