我有一个简单的 C ++ CGI应用程序,从客户端接收 数据。客户端是用C#编写的,并使用 WWWForm 向C ++ CGI应用程序发送和接收数据,所有内容似乎都正常工作 一个 例外即可。
例如,当我向CGI应用程序发送注册表单时,我的CGI应用程序能够接收数据,但当我发送 电子邮件< / strong>对于表单中提供的电子邮件,它使客户端 等待,直到电子邮件已发送,然后断开连接< / strong>即可。
我想处理数据,断开客户端,然后发送电子邮件,因为发送电子邮件需要时间,我希望服务器响应快。
如何断开 客户端与CGI应用程序的连接?目前,客户端断开连接的唯一方法是 CGI应用程序关闭或结束,但 断开连接< / strong>客户过早,以便不必须等待才能将电子邮件完成发送?
我对此进行了在线研究,但没有找到任何解决方案。
答案 0 :(得分:1)
我使用CodeBlocks和MinGW编写了一个非常简单的c ++ cgi。
它所做的就是创建一个分离的进程并直接返回。 它没有读取任何请求。这将留给你。
要将数据传输到新进程,您可能必须将要发送的内容写入文件,然后通过传递给CreateProcess的命令行将该文件的路径提供给新进程。
我使用Xampp测试了cgi。请注意,您必须查看任务管理器以检查过程是否已启动,因为没有窗口会打开。
#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;
}
答案 1 :(得分:1)
您的CGI应用程序只是一个C / C ++程序。考虑到这一点,如果您已经拥有发送电子邮件的代码,只需在另一个线程上运行它。
根据您在项目中配置的内容,您可以使用pthread
或boost::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;
}