Когда клиент подключается к моему серверу через сокет (домен Unix), кажется, что все работает хорошо: соединение устанавливается, запрос обрабатывается, клиент получает ответ, и соединение закрывается. Однако после определенного количества соединений сервер вылетает. Я проверил цикл соединения и обнаружил, что идентификатор соединения, возвращаемый функцией сокета accept()
(завернут в app.newConnectionEstablished()
) продолжает увеличиваться, пока не достигнет предела 1024, и программа не завершится.
Почему идентификатор соединения не всегда сбрасывается на самый низкий доступный номер?
#include <thread>
#include <mutex>
#include <condition_variable>
#include <deque>
#include "UdsServer.hpp"#include "RequestManager.hpp"#include "MSutils.hpp"
RequestManager service;std::deque<std::string> requestQueue;
std::deque<int> connectionQueue;
std::mutex requestQueue_mutex;
std::condition_variable threadSwitch;
bool gotNewRequests = false;void processRequest ()
{
UnixDomainSocket uds;
std::unique_lock<std::mutex> writeLock(requestQueue_mutex);
while (true)
{
while (!gotNewRequests)
threadSwitch.wait(writeLock);
auto currentRequest = requestQueue[0];
auto currentConnection = connectionQueue[0];
requestQueue.pop_front();
connectionQueue.pop_front();
gotNewRequests = false;
writeLock.unlock();
const std::string & response = service.processRequest(currentRequest);
if (response.length())
{
auto ret = uds.sendMsg(currentConnection, response);
if (!ret.isValid())
MF::log("Could not send the response for request.");
}
uds.closeConnection(currentConnection);
writeLock.lock();
}
}int main()
{
UdsServer app;
app.createServer("./App.sock");unsigned n_concThreads = 6;for (int i = 0; i < n_concThreads; ++i)
{
std::thread t (processRequest);
t.detach();
}
int clientConnection = -1;
while ((clientConnection = app.newConnectionEstablished()) > -1)
{
std::string command = app.getMsg (clientConnection);
{
std::unique_lock<std::mutex> writeLock(requestQueue_mutex);
requestQueue.push_back(command);
connectionQueue.push_back(clientConnection);
gotNewRequests = true;
} //Get rid of the lock before notifying the threads
threadSwitch.notify_all(); //nothing happens here if all threads are busy
}
}
Вот как соединения открываются и закрываются (показывая идентификатор соединения):
open 6
close 6
open 7
close 7
open 6
close 6
open 6
close 6
open 6
close 6
open 19
close 19
open 6
close 6
open 6
close 6
open 28
close 28
open 6
close 6
open 6
close 6
open 37
close 37
open 6
...
Задача ещё не решена.
Других решений пока нет …