应用程序崩溃后套接字仍在侦听

发布于 2024-10-08 04:21:07 字数 989 浏览 1 评论 0原文

我在 Windows 2008x64 上使用我的 C++ 应用程序之一时遇到问题(同一应用程序在 Windows 2003x64 上运行得很好)。

崩溃后,甚至有时在定期关闭/重新启动周期后,使用端口 82 上的套接字时会出现问题,它需要接收命令。

查看 netstat,我发现应用程序停止 10 多分钟后套接字仍处于监听状态(该进程肯定不再运行)。

  TCP    0.0.0.0:82             LISTENING

我尝试将套接字选项设置为 REUSEADDR,但据我所知,这只影响重新连接到处于 TIME_WAIT 状态的端口。无论哪种方式,这种改变似乎都没有产生任何影响。

int doReuse = 1;
setsockopt(listenFd, SOL_SOCKET, SO_REUSEADDR,
           (const char *)&doReuse, sizeof(doReuse)); 

我能做些什么来解决或至少避免这个问题?

编辑:

netstat -an 做了,但这就是我得到的全部:

  TCP    0.0.0.0:82             0.0.0.0:0              LISTENING

对于 netstat -anb 我得到:

  TCP    0.0.0.0:82             0.0.0.0:0              LISTENING
 [System]

我知道正常关闭,但即使应用程序因某种原因崩溃,我仍然需要能够重新启动它。相关应用程序使用内部库,该库在内部使用 Windows Sockets API。

编辑:

显然这个问题没有解决方案,因此对于开发,我将使用代理/工具来解决它。感谢所有的建议,非常感谢。

I'm having a problem with one of my C++ applications on Windows 2008x64 (same app runs just fine on Windows 2003x64).

After a crash or even sometimes after a regular shutdown/restart cycle it has a problem using a socket on port 82 it needs to receive commands.

Looking at netstat I see the socket is still in listening state more than 10 minutes after the application stopped (the process is definitely not running anymore).

  TCP    0.0.0.0:82             LISTENING

I tried setting the socket option to REUSEADDR but as far as I know that only affects re-connecting to a port that's in TIME_WAIT state. Either way this change didn't seem to make any difference.

int doReuse = 1;
setsockopt(listenFd, SOL_SOCKET, SO_REUSEADDR,
           (const char *)&doReuse, sizeof(doReuse)); 

Any ideas what I can do to solve or at least avoid this problem?

EDIT:

Did netstat -an but this is all I am getting:

  TCP    0.0.0.0:82             0.0.0.0:0              LISTENING

For netstat -anb I get:

  TCP    0.0.0.0:82             0.0.0.0:0              LISTENING
 [System]

I'm aware of shutting down gracefully, but even if the app crashes for some reason I still need to be able to restart it. The application in question uses an in-house library that internally uses Windows Sockets API.

EDIT:

Apparently there is no solution for this problem, so for development I will go with a proxy / tool to work around it. Thanks for all the suggestions, much appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

请远离我 2024-10-15 04:21:07

如果这只是在调试时对您造成伤害,请使用 sysinternals 人员的 tcpview强制关闭套接字。我假设它适用于您的平台,但我不确定。

如果您在任何套接字上执行阻塞操作,请勿使用无限期超时。根据我的经验,这可能会在多处理器计算机上导致奇怪的行为。我不确定它是什么 Windows 服务器操作系统,但是,它是 2003 Server 之前的一两个版本。
不要使用无限期的超时,而是使用 30 到 60 秒的超时,然后重复等待。如果您正在使用重叠的 IO 和 IOCompletion 端口,这也适用于它们。

如果这是您要发布给其他人使用的应用程序,祝您好运。当使用套接字时,Windows 可能是一个纯粹的混蛋......

If this is only hurting you at debug time, use tcpview from the sysinternals folks to force the socket closed. I am assuming it works on your platform, but I am not sure.

If you're doing blocking operations on any sockets, do not use an indefinite timeout. This can cause weird behavior on a multiprocessor machine in my experience. I'm not sure what Windows server OS it was, but, it was one or two versions previous to 2003 Server.
Instead of an indefinite timeout, use a 30 to 60 second timeout and then just repeat the wait. This goes for overlapped IO and IOCompletion ports as well, if you're using them.

If this is an app you're shipping for others to use, good luck. Windows can be a pure bastard when using sockets...

静谧幽蓝 2024-10-15 04:21:07

我尝试将套接字选项设置为
REUSEADDR 但据我所知
只影响重新连接到端口
处于 TIME_WAIT 状态。

这不太正确。它允许您出于任何目的重新使用处于 TIME_WAIT 状态的端口,即监听或连接。但我同意这对这件事没有帮助。关于操作系统需要 10 分钟才能检测到崩溃的侦听器的评论让我感到惊讶。它应该在进程结束后立即清理除处于 TIME_WAIT 状态的端口之外的所有资源。

I tried setting the socket option to
REUSEADDR but as far as I know that
only affects re-connecting to a port
that's in TIME_WAIT state.

That's not quite correct. It will let you re-use a port in TIME_WAIT state for any purpose, i.e. listen or connect. But I agree it won't help with this. I'm surprised by the comment about the OS taking 10 minutes to detect the crashed listener. It should clean up all resources as soon as the process ends, other than ports in the TIME_WAIT state.

油焖大侠 2024-10-15 04:21:07

首先要检查的是您的应用程序确实正在侦听该端口。使用:

netstat -anb

找出哪个进程正在侦听该端口。

要检查的第二件事是,当应用程序关闭时,您是否正常关闭套接字。如果您使用的是高级套接字 API,那么这应该不是什么太大的问题(您正在使用套接字 API,对吧?)。

最后,您的应用程序是如何构建的?是有螺纹的吗?它会启动其他进程吗?你怎么知道你的应用程序真的被关闭了?

The first thing to check is that it really is your application listening on that port. Use:

netstat -anb

to figure out which process is listenin on that port.

The second thing to check is that your are closing the socket gracefully when your application shuts down. If you're using a high-level socket API that shouldn't be too much of an issue (you are using a socket API, right?).

Finally, how is your application structured? Is it threaded? Does it launch other processes? How do you know that your application is really shut down?

酷到爆炸 2024-10-15 04:21:07

运行

netstat -ano

这将为您提供打开端口的进程的 PID。从任务管理器检查该进程。确保选中“列出所有用户的进程”。

Run

netstat -ano

This will give you the PID of the process that has the port open. Check that process from the task manager. Make sure you have "list processes from all users" is checked.

我不吻晚风 2024-10-15 04:21:07

http://hea-www.harvard.edu/~fine/Tech/ addrinuse.html 是解决“Bind: Address Already in Use”错误的重要资源。

一些摘录:

TIME_WAIT 是进程完成后通常会占用端口几分钟的状态。相关超时的长度因操作系统而异,并且在某些操作系统上可能是动态的,但典型值在一到四分钟的范围内。

避免策略

SO_REUSEADDR

这是减少“地址已在使用”错误的最简单且最有效的选项。

客户首先关闭

如果远端发起关闭,则可以避免TIME_WAIT。因此服务器可以通过让客户端先关闭来避免出现问题。

减少超时

如果(无论出于何种原因)这些选项都不适合您,也可以缩短与 TIME_WAIT 相关的超时。

http://hea-www.harvard.edu/~fine/Tech/addrinuse.html is a great resource for "Bind: Address Already in Use" errors.

Some extracts:

TIME_WAIT is the state that typically ties up the port for several minutes after the process has completed. The length of the associated timeout varies on different operating systems, and may be dynamic on some operating systems, however typical values are in the range of one to four minutes.

Strategies for Avoidance

SO_REUSEADDR

This is the both the simplest and the most effective option for reducing the "address already in use" error.

Client Closes First

TIME_WAIT can be avoided if the remote end initiates the closure. So the server can avoid problems by letting the client close first.

Reduce Timeout

If (for whatever reason) neither of these options works for you, it may also be possible to shorten the timeout associated with TIME_WAIT.

划一舟意中人 2024-10-15 04:21:07

看到https://superuser.com/a/453827/56937后我发现有一个WerFault< /code> 已挂起的进程。

它一定是从不存在的进程继承了套接字,因为杀死它会释放我的监听端口。

After seeing https://superuser.com/a/453827/56937 I discovered that there was a WerFault process that was suspended.

It must have inherited the sockets from the non-existent process because killing it freed up my listening ports.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文