我用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函数来终止整个应用程序。
我知道这不是一个完美的解决方案,我感谢任何建议和提示。
Thanks in advance
构造函数失败时应该抛出异常。c++就是为了很好地处理这个问题而设计的。当且仅当基类和成员已经构造时,它们才被清理。
阻塞来自其他库的函数总是一个问题。Windows和POSIX处理得很好:WSAWaitForMultipleObjectEx
和select
允许你添加一个额外的句柄,你可以用它来解除等待阻塞。
在accept
调用中,您可以通过从主线程通过localhost创建连接来实现此操作。检测到这个"异常"连接将是停止接受进一步连接的信号。
至于openSSL的读取,我只会从主线程关闭套接字,线程安全是该死的。我会确保在关闭的很晚的时候这样做,并且我不期望库在那个时间点之后还能使用。