【问题标题】:Can't connect to local server on Windows无法连接到 Windows 上的本地服务器
【发布时间】:2015-04-20 20:56:55
【问题描述】:

我使用 POCO 库用 C++ 编写的服务器应用程序有一个奇怪的问题。它工作得很好,几天前刚刚停止工作。即使使用 2 周前的 exe 也无法正常工作。

问题是,我无法通过 localhost 连接到服务器,但是我网络外部的其他人可以毫无问题地连接...

我已经在其他计算机上测试过,除了一台计算机之外,它是相同的。 该问题仅存在于 Windows 上。我已经在 Linux 上进行了测试,它运行良好。

这个问题也在http://pocoproject.org/slides/200-Network.pdf的POCO教程代码上重现:

#include "Poco/Net/ServerSocket.h"
#include "Poco/Net/StreamSocket.h"
#include "Poco/Net/SocketStream.h"
#include "Poco/Net/SocketAddress.h"
int main(int argc, char** argv)
{
    Poco::Net::ServerSocket srv(8080); // does bind + listen
    for (;;)
    {
        Poco::Net::StreamSocket ss = srv.acceptConnection();
        Poco::Net::SocketStream str(ss);
        str << "HTTP/1.0 200 OK\r\n"
        "Content-Type: text/html\r\n"
        "\r\n"
        "<html><head><title>My 1st Web Server</title></head>"
        "<body><h1>Hello, world!</h1></body></html>"
        << std::flush;
    }
    return 0;
}

在 Chrome 中输入 127.0.0.1:8080 会导致 ERR_CONNECTION_ABORTED。 http://www.canyouseeme.org/ 报告它可以在端口 8080 上看到我的服务。

其他应用程序(我猜不使用 POCO?)工作正常。

我完全不知道这个问题的原因是什么...... 如有任何建议,我将不胜感激。

【问题讨论】:

  • 看起来像防火墙、间谍软件(垃圾邮件代理)或 dll 地狱问题。您是否尝试在另一个端口上启动?也许某些服务正在使用此端口,但没有使用 http?可以用net cat测试吗?下载 net cat 并启动 nc -lp8080 和另一个实例 nc 127.0.0.1 8080。它们连接了吗?
  • 从另一个端口启动并不能解决问题。没有其他服务也没有使用此端口。是的,他们连接:screenshooter.net/102449625/xdwtuqk
  • 本月的 Windows 更新是否引入了问题?
  • 这是我的第一个怀疑,虽然我已经创建了一个干净的Windows 7安装的虚拟机,但问题仍然存在。
  • @ValentinHeinitz 我也不认为这是 dll 地狱问题。我已将服务器与静态库链接(exe 仅依赖于 kernel32、advapi32、ihlpapi 和 ws2_32),但问题仍然存在。

标签: c++ windows poco-libraries


【解决方案1】:

我已经尝试过您的示例。它看起来像正常行为。如果它曾经工作过,那是相当不正常的。是不是,您已经更新了 Chrome 或之前使用一些旧版浏览器进行了测试?

在该示例中,服务器正在发送数据并立即关闭连接。我认为,POCO 中应该有一个命令以更优雅的方式终止连接。

该示例似乎演示了非常简单,但不符合协议的服务器响应。尝试使用 HTTPRequestHandlerFactory。这样服务器似乎不会在每次请求后终止连接。

Firefox 显示很短的 “Hello World!”,然后显示“连接中止”

Chrome 中的ERR_CONNECTION_ABORTED 也可能意味着服务器意外关闭了连接。

curl 在大多数情况下显示:

C:\bin>curl.exe http://localhost:8080
curl: (56) Recv failure: Connection was reset

但在极少数情况下:

C:\bin>curl.exe http://localhost:8080
<html><head><title>My 1st Web Server</title></head><body><h1>Hello, world!</h1></body></html>

curl: (56) Recv failure: Connection was reset

flush 之后添加Sleep(100) 后,html 内容始终显示在Recv failure 之前。因此,取决于浏览器是否显示内容的时间。

可能有 linux 上不同行为的提示:

void HTTPServerConnection::onServerStopped(const bool& abortCurrent)
{
    _stopped = true;
    if (abortCurrent)
    {
        try
        {
            // Note: On Windows, select() will not return if one of its socket is being
            // shut down. Therefore we have to call close(), which works better.
            // On other platforms, we do the more graceful thing.
#if defined(_WIN32)
            socket().close();
#else
            socket().shutdown();

【讨论】:

  • 那为什么这个错误只出现在本地网络内部,而外部没有问题呢?另外,我的完整代码在一段时间后没有关闭连接仍然不起作用。
  • 那么,来自外部的连接有效吗?您只提到了 canyouseeme.org,它不能真正测试 HTTP 堆栈。您真的可以从另一台计算机连接浏览器吗?您可以在本地计算机上尝试curl.exe -v 吗?输出是什么?
  • 我已经提到“来自我网络外部的其他人可以毫无问题地连接”:) 是的,从外部访问浏览器中的 my.ip.address:8080 就像一个魅力。卷曲输出:pastebin.com/ZHjsGwby
  • 奇怪,今天我的服务器应用程序可以工作了......不过我没有改变任何东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-12-09
  • 2013-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-20
  • 2018-10-17
相关资源
最近更新 更多