0

我的应用程序是一个服务器应用程序,它接受来自用户的一些预定义命令并显示从服务器端存在的 XML 文件获取的相应输出。

为了解析 XML 文件,我使用的是 apache 的 xerces-c 库版本 3.1.2。该应用程序在终端上手动运行时运行良好。

但我想通过网络上的 telnet 运行应用程序,这样我就可以通过 telnet 向应用程序提供输入,也可以在远程系统上接收输出。为此,我使用了 inetd 超级服务器,并在 inetd.conf 中添加了以下行:

vterm stream tcp nowait root /path/to/my/binary/vterm vterm

然后在 /etc/services 中添加以下行以使其侦听端口 5000

vterm 5000/tcp

之后,当我尝试连接到我的应用程序时,我曾经收到以下消息:

msatyam@sabayon ~/programming/cpp/xml $ telnet localhost 5000
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Connection closed by foreign host.

当上面的连接关闭消息出现时,我认为我没有使用 inetd 正确配置我的应用程序。所以,我用一个不使用任何额外库的简单二进制文件替换了我的二进制文件。只是简单的 cin's 和 cout's,效果很好。

然后事实证明我的应用程序有问题,所以为此我投入了大量的 cout 来确定实际发生了什么。有了这个,我发现其中一个 xerces-c XML 解析库函数正在返回 NULL,并且通过这个 NULL 引用,我试图在下面的行中调用一个函数,它会在我的应用程序启动时立即转储。

但是当我在终端上手动运行我的应用程序时,相同的功能工作正常。完整的应用程序有点大,所以我创建了一个重现问题的演示代码。这是我的代码:

    #include <xercesc/util/PlatformUtils.hpp>
    #include <xercesc/parsers/XercesDOMParser.hpp>
    #include <xercesc/dom/DOMDocument.hpp>
    #include <xercesc/dom/DOMElement.hpp>
    #include <iostream>

    using namespace std;
    using namespace xercesc;

int main()
{
    try
    {
        // init xerces XML Parser library
        XMLPlatformUtils::Initialize();
    }
    catch (const XMLException& ex)
    {
        cerr << ex.getMessage() << endl;
    }

    // parse a XML file
    XercesDOMParser* parser = new XercesDOMParser();
    try
    {
        parser->parse("sample.xml");
    }
    catch (const XMLException& ex)
    {
        cerr << ex.getMessage() << endl;
    }

    // get the document reference
    DOMDocument* doc = parser->getDocument();

    if (doc == NULL)
    {
        cout <<"Doc is NULL" << endl;
    }

    // else do stuff further
    // like get root element
    DOMElement* root = doc->getDocumentElement();

    // print node name
    string name = XMLString::transcode(root->getTagName());
    cout << "Name: " << name << endl;

    XMLPlatformUtils::Terminate();
return 0;
}

上面的代码在手动编译和运行时不会进入 if 条件,即“Doc is NULL”并成功打印根元素标记名称,但是当我在 inetd 后面运行这个应用程序并且当我 telnet 到它时,我能够看到“Doc is NULL”语句和同一条消息“连接被外部主机关闭”之后。因为我的应用程序可能会倾销。

我现在有点没脑子,因为我不知道该去哪里找。由于相同的代码在手动运行但不是通过 inetd 时有效。所以,我想我们在通过使用共享库的 inetd 执行进程时是否需要特别注意,就像这里我使用 xerces-c 共享库进行 XML 解析一样。或者我的理解或我的代码可能还有什么问题。当应用程序手动运行而通过 inetd 运行时,相同的库函数如何工作得很好?

我尝试使用 xinetd 而不是 inetd 进行相同的操作,但结果相同。

4

1 回答 1

1

正如您已经证明的那样,工作目录是/您通过inetd. 但是您的 XML 文件不在系统的根目录中。您可以将完整路径硬连线到您的应用程序中。更好的解决方案是将文件的位置作为参数传递。

于 2015-08-17T20:14:29.193 回答