о вызове Select

Тема в разделе "Общие вопросы по С и С++", создана пользователем debug, 6 апр 2006.

Статус темы:
Закрыта.
  1. debug

    debug Гость

    Репутация:
    0
    Сначала опишу в кратце - решил я воспользоваться вызовом select при общении с TCP сервером. Сервер не моей разработки - пакетики шлёт странно как то - небольшими порциями - иногда байт по 20. Но так получилось - что без него нни куда %(
    причина ясна - хотя сокет планирую открывать с ним пока один - но решил через select пообщаться. Примерно код такой
    сначала создание сокета PF_INET, как обычно, затем connect - конектится всё в порядке, затем:

    for (;:( {
    fd_set rfdset, wfdset;
    FD_ZERO(&rfdset);
    FD_ZERO(&wfdset);
    if (!readden) {
    FD_SET(sock, &rfdset);
    cout<<"readden=false\n";
    }
    if (!written) {
    FD_SET(sock, &wfdset);
    cout<<"written=false\n";
    }
    memset(read_buf, 0, sizeof(read_buf));
    int rc=select(sock+1, &rfdset, &wfdset, NULL, &tv);
    if (!rc) {
    closesocket(sock);
    exit_error("timeout", WSAGetLastError());
    }
    if (rc<0) {
    closesocket(sock);
    exit_error("error select - WSAGetLastError: ") }
    if (FD_ISSET(sock, &rfdset)) {
    out(" есть данные для чтения");
    int count_byte=recv(sock, read_buf, sizeof(read_buf), 0);
    out("получены данные - байт:");
    out(read_buf);
    // if (count_byte==30) {
    // readden=true;
    // written=false;
    }
    }
    if (FD_ISSET(sock, &wfdset)) {
    out("возможна запись данных");
    int sent_byte=send(sock, write_buf, strlen(write_buf), 0);
    out("записано в порт байт: ");
    out(sent_byte);
    // if (sent_byte==strlen(write_buf)) {
    // written=true;
    // readden=false;
    }
    }
    }
    Суть вопросов:
    1. Какие нужно опции ставить на сокет (setsockopt) перед использованием в select?
    2. В каком режиме нужно "отдавать" select-у сокет - блокируемом или наоборот, тоже опционально setsockopt?
    3. В моём примере с учётом комментариев всё работает - но вот какая штука,
    я написал быстренько сервер - который сначала порцию байт принимает - затем отправляет клиенту небольшую порцию байт. Так вот весь прикол в следующем:
    если timeval tv установлен больше 1 секунды - то происходит вот что - клиент сначала в сокет серверу одни и теже данные - много раз (хотя сервер принимает один пакет и сразу отправляет ответ), затем много раз читает из сокета пришедший от сервера пакет. Если tv установить в 0 - то клиент вообще ничего не успевает прочитать.
    Я думал - что select работает таким образом - что однажды отправленные данные уже не отправит и не будет из буфера читать одно и тоже много раз. Выходит я сам должен управлять набором сокетов, переключая его в селекте в режим чтения или записи дабы избежать записи или чтения уже принятых или отправленных многократно данных???
    Если есть конкретный у кого пример - напишите пожалуста
     
Загрузка...
Статус темы:
Закрыта.

Поделиться этой страницей