Использование Telnet для тестирования select ()

Я довольно новичок в программировании на Linux/сокет. Я использую select для проверки соединений в моей серверной программе (в конечном итоге это будет сервер чата). Я использую telnet, чтобы проверить его, и что-то странное происходит. Когда я сначала запускаю telnet (telnet localhost 5794), select возвращает 1 и добавляет новое подключение в список описателей мастер-файлов. Все выглядит хорошо.

Но потом я пытаюсь вводить вещи в telnet, и ничего не происходит. Выберите return 0, если я не открою новый сеанс telnet.

Является select только для поиска новых подключений? Я думал, что смогу использовать его для проверки ввода. Ниже приведена копия моего кода (сейчас это немного грязно, потому что я в ярости испортил его последние пару часов. Извините)

#include "chatpacket.cpp"
#include "serverFunctions.cpp"

#define SERVER_PORT 5794
#define MAX_PENDING 10

int main() {
  fd_set connections;
  fd_set waitingConnections;
  user *clients = new user[50];
  int serverSocket = ServerSetup (SERVER_PORT, MAX_PENDING);
  int maxFD = serverSocket;
  int ConnectionCount;

  struct timeval tv;

  FD_ZERO(&connections);
  FD_SET(0, &connections);
  FD_SET(serverSocket, &connections);

  tv.tv_sec = 1;
  tv.tv_usec = 100;

  bool shutdown = false;
  bool tmpflag = true;
  while(!shutdown) { 

    if (tmpflag == true){printf("in the loop!\n");tmpflag=false;}
    waitingConnections = connections;

    ConnectionCount = select((maxFD+1), &waitingConnections, NULL, NULL, &tv);

    if (ConnectionCount == -1) {
        ///HANDLE ERROR!!!!!!
        printf("Connection Error!");
    }
    else if (ConnectionCount > 0) {
      if (FD_ISSET(serverSocket, &waitingConnections)){
           newConnection(serverSocket, connections, maxFD, clients); //this works fine
      }
      else {
           checkConnections(clients, waitingConnections, maxFD); //the code never gets here
      }
    }

    //check keyboard
    shutdown = checkKeyboard();

  }
}

EDIT: Вот код для newConnection:

bool newConnection(int serverSocket, fd_set& ConnectionList, int maxFD, user* userGroup){
    printf("in newConnection\n");
    struct sockaddr_storage remoteaddr;

    socklen_t addrlen = sizeof remoteaddr;

    int newFD = accept(serverSocket,(struct sockaddr *)&remoteaddr,&addrlen);
    FD_SET(newFD, &ConnectionList);

    if (newFD > maxFD)
        maxFD = newFD;

    printf("We have a new connection!!! (newConnetcion)\n");

    bool userAdded = false;
    for (int i = 0; i < 50; i++){
      if (userGroup[i].active == false){
            userGroup[i].socket = newFD;
            userGroup[i].active = true;
            userAdded = true;
                        printf("User added in the %ith position of the array.(socket number %i)\n",i,newFD);
            break;
      }
    }
    if (!userAdded)
        printf("new user was not added! (newConnetcion)\n");
}

Функция checkConnections имеет printf в начале, поэтому я могу видеть, когда она входит в эту функцию. Он никогда не печатает.

1
После возврата select вы вызываете accept , правильно? А затем вы вызываете read в сокете, возвращаемом accept ?
добавлено автор Dietrich Epp, источник
read и recv в основном аналогичны для сокетов. Увеличивает ли maxFD прирост? Вы когда-нибудь добавляли новый сокет в fd_set?
добавлено автор Dietrich Epp, источник
Нет причин для финала «еще». Вы можете получать входящие соединения и входящие данные одновременно.
добавлено автор EJP, источник
Функция newConnect вызывает Accept и добавляет дескриптор файла, возвращенный в главный список, но я не вызывал его чтение ... Я попробую это сейчас.
добавлено автор James - not really a pirate, источник
Хорошо. Я не уверен, что это должно делать. Функция checkConnections вызывает recv для ввода ввода. Должен ли я использовать для этого чтение? Или прочитайте, позвольте мне позвонить в recv позже.
добавлено автор James - not really a pirate, источник
да и да. Я добавил код для checkConnections к вопросу. Это, наверное, что-то простое, что мне просто не хватает. Я действительно ценю твою помощь.
добавлено автор James - not really a pirate, источник

1 ответы

Вот проблема.

int main(int argc, char *argv[])
{
    int maxFD = ...;
    ...
    newConnection(..., maxFD, ...);
    ...
}

void newConnection(..., int maxFD, ...)
{
    ...
    if (newFD > maxFD)
        maxFD = newFD;
    ...
}

Обратите внимание, что есть две переменные с именем maxFD : один в функции main и один в функции newConnection . Изменение одного не меняет другого. Рекомендация: используйте глобальный вариант. (Причина: для всего приложения есть только одно приложение, и многие функции должны получить к нему доступ.)

Это очень простая ошибка. Если вы не нанесете на лоб и не говорите: «О, это очевидно», тогда вы, возможно, захотите вернуться и ознакомиться с вступительным словом к книге программирования.

1
добавлено
Огромное спасибо!!! Это полностью фиксировало это. Вы, сэр (или мэм), мой герой!
добавлено автор James - not really a pirate, источник
Да. Я чувствую себя глупо.
добавлено автор James - not really a pirate, источник
pro.cxx
pro.cxx
3 049 участник(ов)

C/C++ chat 0. Простые вопросы, лабы и о IDE — в чат новичков @supapro 1. Не хамим, не переходим на личности, не вбрасываем утверждения без доказательств 2. No Ads, offtop, flood Объявления о вакансиях и евенты - в лс @AlexFails https://t.me/ProCxx/259155

supapro.cxx
supapro.cxx
1 925 участник(ов)

Чат для тех, кто немного знает C++, простые вопросы по реализации, синтаксису и ide – сюда, а для другого есть: /Главный чат по серьезным вопросам — @ProCxx /Чат по обсуждению всего — @fludpac

C++ Russia
C++ Russia
384 участник(ов)

Сообщество разработчиков C++ в Telegram.

cxx.Дискуссионная
cxx.Дискуссионная
298 участник(ов)

это не двач, общайтесь вежливо; разговор на почти любые темы; Не согласны с баном? В лс @AlexFails, @ivario

C++ для маленьких и тупых
C++ для маленьких и тупых
105 участник(ов)

Лоу левел (по среднему IQ участников) чатик ExtremeCode @extremecode Флудилка @extremecode_rest