Модераторы: feodorv

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Сокеты: виснет recv 
:(
    Опции темы
Alca
Дата 25.6.2009, 20:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

Репутация: 1
Всего: 50



Код

std::string CXTcpClientSocket::sRecvBytes(INT iFlags) {
    std::string sRes             = "";
    CHAR        szBuff[1024 + 1] = {0};

    while (TRUE) {
        ULONG ulArg = 0;
        if (0 != ::ioctlsocket(m_puiSocket, FIONREAD, &ulArg)) {
            break;
        }

        if (0 == ulArg) {
            break;  //<-- сюда валиться
        }

        if (1024 < ulArg) {
            ulArg = 1024;
        }

        INT iRes = ::recv(m_puiSocket, szBuff, ulArg, 0);
        if (iRes <= 0) {
            break;
        }

        std::string sTemp;

        sTemp.assign(szBuff, iRes);
        sRes += sTemp;
    }

    return sRes;
}

Все равно нет ответа от сервера....  smile 

Это сообщение отредактировал(а) Alca - 25.6.2009, 21:14


--------------------
PM WWW ICQ Skype Jabber   Вверх
fry
Дата 26.6.2009, 08:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 257
Регистрация: 4.10.2006

Репутация: нет
Всего: 3



Alca, может данные просто дойти не успевают? 

Пробовал вызывать CXTcpClientSocket::sRecvBytes через некоторые промежутки времени?
PM MAIL   Вверх
Alca
Дата 26.6.2009, 09:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

Репутация: 1
Всего: 50



Цитата

Alca, может данные просто дойти не успевают? 

::ioctlsocket говорит что нет данных для чтения 
Код

        if (0 == ulArg) {
            break;  //<-- сюда валиться
        }

хотя ответ от сервера еще не пришел.
Цитата

Пробовал вызывать CXTcpClientSocket::sRecvBytes через некоторые промежутки времени?

До ::recv дело не доходит


--------------------
PM WWW ICQ Skype Jabber   Вверх
Alca
Дата 26.6.2009, 13:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

Репутация: 1
Всего: 50



Если я принимаю данные большого размера (файл) в буфер фиксированого размера:
Цитата

CHAR szBuf[8192];
INT iRes = ::recv(&szBuf[0], 8192, 0);

Кол-во принятых байт будет всегда равно размеру принимающего буфера или нет
(я не беру, тот факт, что концовка данных (файла) будет меньше размера буфера, это и так ясно) ?
Цитата

assert(iRes == 8192); //???




--------------------
PM WWW ICQ Skype Jabber   Вверх
fry
Дата 26.6.2009, 15:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 257
Регистрация: 4.10.2006

Репутация: нет
Всего: 3



нет, не так. 

Функция чтения из сокета не обязанна возвращать значение считанных байт, равное требуемому. Именно для обработки данного условия она это значение и возвращяет. 

Представь себе ситуацию, что ты передаешь фильму метров эдак на 500. Естественно она вся в буфер приема ОС для этого сокета не влезет. Тогда как спрашивается функция приема данных вернет тебе запрошенные у нее 500 метров?

Чтобы считать данные необходимо выделить буфер, запросить все данные, функция вернет значение считанных байт, если оно меньше требуемого, то корректишь входные данные функции в соответствии с ним (корректируешь смещение в буфере на возвращенное значение и уменьшаешь значение количества байт на считывание) и т.д.. Иными словами необходимо вызывать функцию приема данных такое количество раз, которое обеспечит тебе необходимое количество байт данных.
Если сокет будет неблокируемым, то пр и этом будет очень много итераций. Неблокированный сокет тебе пригодится если необходимо обеспечить некоторое количество соединений, но алгоритм будет несколько иной. Можешь породить поток, где вызовешь функцию на блокируемом сокете.

Некоторые параметры работы данного алгоритма можно настаивать. Я уже посоветовал книгу ("UNIX. Разработка сетевых приложений", Стивенс) - в ней все есть.

Это сообщение отредактировал(а) fry - 26.6.2009, 15:08
PM MAIL   Вверх
Alca
Дата 26.6.2009, 15:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

Репутация: 1
Всего: 50



Хм.... Кажись я близок к цели..... smile 
Смотрю, я первую ответку сервера, которая пришла типа не полностью....
Как вы думаете, какой размер этих данных?
1024 байта. Следов. сервак шлет мне эти данные блоками по 1024 байт.
Ну поставил я у себя такой же размер буфера и все заработало.
Вот код:
Код

std::string CXTcpClientSocket::sRecvBytes() {   
    std::string  sRes      = "";
    INT          iRes      = etError;   
    BOOL         bRes      = FALSE;   
    const size_t cuiInSize = 1024; ///////////////////////
    std::string  sIn(cuiInSize, '\0');

    for (;;) {   
        iRes = iRecv(&sIn[0], cuiInSize, 0);  
        assert(iRes >= 0);
        assert(iRes <= cuiInSize);
        
        if (0 == iRes) {
            break;
        }    
        if (- 1 == iRes) {
            break;
        }

        std::string sTemp(sIn.begin(), sIn.begin() + iRes);
        sRes.append(sTemp);

        if (iRes < cuiInSize) {   
            ULONG ulArg = (ULONG)FALSE;    
            if (0 != ::ioctlsocket(_m_puiSocket, FIONREAD, &ulArg)) {
                break;
            }

            if (0 == ulArg) {
                break;
            }
        }
    } 

    return sRes;    



Добавлено через 1 минуту и 3 секунды
Но как быть если размер буфера у меня не 1024 байта?  smile 


--------------------
PM WWW ICQ Skype Jabber   Вверх
GrayCardinal
Дата 26.6.2009, 15:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Фигасе
****


Профиль
Группа: Завсегдатай
Сообщений: 3039
Регистрация: 9.11.2003

Репутация: 3
Всего: 58



Цитата

и все заработало.

Я рад за тебя...  smile  


--------------------
PM MAIL WWW   Вверх
fry
Дата 26.6.2009, 15:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 257
Регистрация: 4.10.2006

Репутация: нет
Всего: 3



в одном пакете TCP умещается около 1500 байт
PM MAIL   Вверх
Alca
Дата 26.6.2009, 15:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

Репутация: 1
Всего: 50



Цитата

Цитата
Цитата

и все заработало.

Я рад за тебя...

Но как быть если размер буфера у меня не 1024 байта?

Добавлено через 1 минуту и 23 секунды
Цитата

в одном пакете TCP умещается около 1500 байт
 и?


--------------------
PM WWW ICQ Skype Jabber   Вверх
GrayCardinal
Дата 26.6.2009, 15:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Фигасе
****


Профиль
Группа: Завсегдатай
Сообщений: 3039
Регистрация: 9.11.2003

Репутация: 3
Всего: 58



Alca
А в репу ?  smile

Добавлено через 19 секунд
ЗЫ
ради приличия хотя бы по RTF эмь


--------------------
PM MAIL WWW   Вверх
Alca
Дата 26.6.2009, 15:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

Репутация: 1
Всего: 50



Цитата

А в репу ? 
  smile 


--------------------
PM WWW ICQ Skype Jabber   Вверх
Страницы: (3) Все 1 2 [3] 
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Сети | Следующая тема »


 




[ Время генерации скрипта: 0.0805 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.