断开连接到 cgi 应用程序的客户端

Disconnect Client connected to cgi application

我有一个简单的 C++ CGI 应用程序,它 接收 形式的 data =]客户。客户端是用 C# 编写的,使用 WWWForm 向 C++ CGI 应用程序发送和接收数据,一切似乎都在 working with 一个 异常

例如,当我向 CGI 应用程序发送注册表单时,我的 CGI 应用程序能够 接收 数据,但是当我 发送 一个 email 到表单中提供的电子邮件,它使 clientwait 直到电子邮件 已发送 ,然后 断开连接

我想处理数据,断开客户端然后发送电子邮件因为发送电子邮件需要时间而且我希望服务器响应速度快。

如何从 CGI 应用程序断开 客户端?目前,客户端断开连接的唯一方法是 CGI 应用程序关闭结束 存在 一种断开客户端过早的方法,这样它不必等待 电子邮件完成 发送?

我对此进行了在线研究,但没有找到任何单一的解决方案。

我使用 CodeBlocks 和 MinGW 编写了一个非常简单的 c++ cgi。

它所做的只是创建一个分离的进程并直接returns。 它不读取任何请求。那将留给你。

要向新进程获取数据,您可能必须将要发送的内容写入文件,然后通过传递给 CreateProcess 的命令行将该文件的路径提供给新进程。

我使用 Xampp 测试了 cgi。请注意,您必须查看任务管理器以检查进程是否已启动,因为 window 不会打开。

#include <iostream>
#include "windows.h"

using namespace std;

int main()
{
    cout << "Content-type: text/html\n\n";
    cout << "<html><head></head><body>";

    cout << "Hello world! I'm starting a batch job";

    cout << "</body></html>" << endl;

    STARTUPINFO siStartupInfo = {sizeof(STARTUPINFO)};

    siStartupInfo.cb = sizeof(siStartupInfo);
    siStartupInfo.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
    siStartupInfo.wShowWindow = SW_HIDE;

    PROCESS_INFORMATION piProcessInfo;

    CreateProcess(NULL, (LPSTR)"\"D:\Program Files (x86)\CodeBlocks\codeblocks.exe\" ",
    0, 0, false, CREATE_DEFAULT_ERROR_MODE | CREATE_NO_WINDOW | DETACHED_PROCESS , 0, 0,
    &siStartupInfo, &piProcessInfo);

    cout << "I created a new process!";

    return 0;
}

您的 CGI 应用程序只是一个 C/C++ 程序。考虑到这一点,如果您已经有了发送电子邮件的代码,只需 运行 在另一个线程上。

根据您在项目中的配置,您可以使用 pthreadboost::thread

线程创建示例使用 pthread:

#include <pthread.h>
#include <iostream>

typedef struct{
    // Sample parameters, use your own.
    std::string subject;
    std::string sender;
    std::string recipient;
    std::string message;
} EmailData;

void* do_send_mail(void* void_ptr)
{
    EmailData* data = (EmailData*)void_ptr;

    // your code that sends the email

    delete data;
    return NULL;
}

int main()
{
    // Thread handle
    pthread_t send_mail_thread;

    // Your email struct
    EmailData* email = new EmailData;

    email->subject = "Testing email.";
    email->recipient = "nobody@example.com";
    email->sender = "youremail@example.com";
    email->message = "You just won one billion dollars!";

    if(pthread_create(&send_mail_thread, NULL, do_send_mail, (void*)email)) {

        std::cout << "Failed to create thread that sends the email." << std::endl;
        return 1;

    }

    // Remove this "join" in your CGI application, it waits for the thread to
    // finish (which will make your client wait just like it does now)
    pthread_join(send_mail_thread, NULL);

    return 0;
}

线程创建示例使用 boost::thread:

#include <boost/thread.hpp>

typedef struct{
    // Sample parameters, use your own.
    std::string subject;
    std::string sender;
    std::string recipient;
    std::string message;
} EmailData;

void do_send_mail(EmailData& email)
{
    // your code that sends email here
}

int main(int argc, char* argv[])
{

    EmailData email;
    email.subject = "Testing email.";
    email.recipient = "nobody@example.com";
    email.sender = "youremail@example.com";
    email.message = "You just won one billion dollars!";

    boost::thread email_thread(boost::bind<void>(do_send_mail, email));

    // Remove this "join" in your CGI application, it waits for the thread to
    // finish (which will make your client wait just like it does now)
    email_thread.join();

    return 0;
}

使用 boost::thread(使用 lambda)创建线程的示例:

#include <boost/thread.hpp>

typedef struct{
    // Sample parameters, use your own.
    std::string subject;
    std::string sender;
    std::string recipient;
    std::string message;
} EmailData;

int main(int argc, char* argv[])
{

    EmailData email;
    email.subject = "Testing email.";
    email.recipient = "nobody@example.com";
    email.sender = "youremail@example.com";
    email.message = "You just won one billion dollars!";

    boost::thread email_thread(boost::bind<void>([](EmailData& email)->void{

        // your code that sends email here

    }, email));

    // Remove this "join" in your CGI application, it waits for the thread to
    // finish (which will make your client wait just like it does now)
    email_thread.join();

    return 0;
}