Будет ли этот подход работать?Обработка нескольких клиентов и отдельных серверов
Я просто представляю свой код в упрощенной форме для удобства чтения. Я пытаюсь реализовать несколько клиентских/один TCP-сервер.
Мой слушатель будет цикл, как это (как нить), который обрабатывает соединения
void WaitAndAcceptConnection(){
if(socket_TEMP = accept(sock_LISTEN, (SOCKADDR*)&ADDRESS, &AddressSize))
{
socketsManager.push_back(socket_TEMP);
currCount++;
std::cout<<"\n A connection was found!"<<std::endl;
send(socketsManager[currCount], "Welcome! you have connected to Athena Server", 46,NULL);
// cond.notify_one(); //notify the waiting thread
}
}
, где я есть ..
std::vector<SOCKET> socketsManager; //handles socket
int currCount=-1; //keep track on the number of connections
Если клиент подключен, то currCount будет увеличен на единицу , в нашем случае это будет currCount = 0
, а затем socketsManager[0]
сохранит возврат accept. Если другой подключен, то currCount = 1
, то socketsManager[1]
будет его обработчиком.
Для отправки и получения данных.
Я собираюсь сделать цикл for, который будет продолжаться итерацией, чтобы проверить, есть ли данные recv'd (-1 или 0) для всех сокетов, которые обрабатываются моей программой.
void WaitAndAcceptCommands(){
for(int i = 0; i<= currCount;i++){
int result = recv(socketsManager[i],&command,1,0);
if(result ==-1){
}
else if(result == 0){
}
else{
//process commands
}
}
}
Главная будет что-то вроде этого
Athena ath2; //instance of the server
std::cout<<"\n >Waiting for incoming connections..."<<std::endl;
//listener thread, just keep on LOOPING
std::thread connectionThread([&](){
while(1){
ath2.WaitAndAcceptConnection();
}
});
//handles all the inputs, JUST KEEP ON LOOPING
std::thread commandsThread([&](){
while(1){
ath2.WaitAndAcceptCommands();
}
});
connectionThread.join(); //stop
commandsThread.join(); //stop
Я бы с удовольствием показать остальную часть моего кода, но они находятся в полном беспорядке прямо сейчас. Я только хотел представить идею, если это сработает, и тогда я продолжу ее, если не тогда, я передумаю другой метод. Я планирую обрабатывать свои подключения через timeouts
, если мне когда-нибудь придется сбросить сокет из моего std::vector<SOCKET> socketsManager;
с помощью remove. Это хороший метод? если нет, то какие проблемы?
Чтение о 'select' атм, но я любопытное путать о том, как это работает. –
Есть два способа решить проблему. Чем проще использовать блокировку ввода-вывода по умолчанию, цикл принимает и создает новый поток для каждого принятого соединения. Второй метод - использовать неблокирующий ввод-вывод и использовать 'select()' или 'poll()'. Неблокирующийся ввод-вывод истекает или возвращается с установленным набором FD. Вы несете ответственность за выбор или опрос FD. – alvits
'select()' и 'poll()' хороши для однопоточных приложений. Он позволяет коду обрабатывать несколько файловых дескрипторов (сокетов). Блокирование ввода-вывода легче писать, но не очень хорошо для одиночных процессов, однопоточных кодов. Используйте несколько процессов или несколько потоков. – alvits