我在c ++服务器上编写的服务器就像代理服务器一样。主要功能:
try
{
Connector c(ip); //establishes persistent connection to the server B
Listener1 l1(port); //listens incoming connection to the server A (our proxy) and push them into the queue
Listener2 l2(&c); //listens responses (also push messages) from the server B and push them into the queue
Proxy p(&c, &l1, &l2); //pulls clients out from the queue and forwards requests to the server B, pull out everything from the listener2 queue and returns as a responce
KeepAlive k(&l1, &p); //pushes the empty client to the listeners1's queue thus the proxy sends keepalive to the server B and the response is discarded
l1.start();
p.start();
l2.start();
k.start();
l1.join();
p.join();
l2.join();
k.join();
catch(std::string e)
{
std::cerr << "Error: " << e << std::endl;
return -1;
}
现在我有以下问题/怀疑:
** 1. **我从构造函数中抛出一个异常,这是一个好习惯吗?当无法建立连接时抛出异常,这就是为什么不应该创建对象的原因。
** 2. **关闭应用程序安全性并在发生连接超时或服务器B关闭连接等时出现问题。 listener1和listener2使用阻塞函数(系统调用accept()和来自openssl lib的BIO_read)因此不可能只从另一个线程设置循环条件。问题还在于所有模块都已连接并使用互斥锁共享资源。我当前的一段代码只是调用exit函数来终止整个应用程序。
我知道这不是一个完美的解决方案,我感谢任何建议和提示。
提前致谢
答案 0 :(得分:2)
如果构造函数失败,它们应该抛出异常。 C ++旨在很好地处理这个问题。当且仅当它们已经构建时,基类和成员才被清理。
阻止其他库中的函数始终存在问题。 Windows和POSIX处理得很好:WSAWaitForMultipleObjectEx
和select
允许您添加一个额外的句柄,您可以使用它来取消阻止等待。
在accept
调用中,您可以通过主线程通过localhost创建连接来伪装它。检测到这种“异常”连接将是一个停止接受进一步连接的信号。
对于openSSL读取,我只是从主线程中关闭套接字,threadafety是安全的。我会确保在关机后很晚才这样做,并且我不希望在此之后该库可以使用。