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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> WinAPI Socket, recv, узнать кол-во байт под буфер 
:(
    Опции темы
ivsh
Дата 19.11.2013, 10:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Приветствую, форумчане!
Пишу сетевое приложение. Возник вопрос с функцией recv, прием данных из сокета.
В ней нужно указывать буфер и его размер, а как мне узнать сколько выделить памяти под буфер?
Если я статически буду выделять 1кБ, а прийдут данные на 1МБ, то я не получу остальную часть.

Программа. Протокол TCP/IP. Сокет создаю в потоковом режиме, то есть
Код

mysocket = socket(AF_INET, SOCK_STREAM, 0)

Далее по коду, читаю данные
Код

dataReceivedTotal = recv(my_sock, dataReceived, 1024, 0)

где dataReceived - буфер, 1024 - размер буфера, а dataReceivedTotal - кол-во полученных байтов.
Дело в том, что я не знаю сколько байт пришло или как это определить, чтобы выделить соотв. по размеру буфер.
Функция recv возвращает кол-во принятых байт уже после записи в буфер.
Вот как определить какого размера выделить буфер под принимаемые данные?

И второй вопрос.
 Работаю с сокетом в цикле, отправляю данные клиенту, назовем ДАННЫЕ1 , при этом принимаю данные от клиента, если от клиента что-то пришло, то обрабатываю его запрос и отправляю ему РЕЗУЛЬТАТ1 + ДАННЫЕ1, иначе просто ДАННЫЕ1. 
 Примерно так:

Код

while (true)
{
    // Принимаю данне.
    dataReceivedTotal = recv(my_sock, dataReceived, 1024, 0);
    if (dataReceivedTotal > 0)
    {
        // Обработка данных пользователя.
    }
    else
    {
        // Отправляю стандартные данные.
    }
}


Выход из цикла должен осуществляться, если пользователь закрыл соединение.
 В документации написано:
Цитата

If the connection has been gracefully closed, the return value is zero.

Если соединение закрыто успешно, то получите 0.
 Собственно вопрос, как мне различать состояния, когда пользователь ничего не прислал и когда он закрыл соединение?
PM MAIL   Вверх
feodorv
Дата 19.11.2013, 19:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 10
Всего: 45



Цитата(ivsh @  19.11.2013,  11:32 Найти цитируемый пост)
то я не получу остальную часть

Почему? Получите частями при следующих чтениях из сокета...

Цитата(ivsh @  19.11.2013,  11:32 Найти цитируемый пост)
Функция recv возвращает кол-во принятых байт уже после записи в буфер.

Если Вам интересно число доступных для чтения байт до recv, то можете воспользоваться вызовом ioctl( FIONREAD ), например, для виндов:
Код
  unsigned long v = 0;
  if( (rv = ioctlsocket( sock, FIONREAD, &v)) == SOCKET_ERROR ) /* error */



Цитата(ivsh @  19.11.2013,  11:32 Найти цитируемый пост)
Собственно вопрос, как мне различать состояния, когда пользователь ничего не прислал и когда он закрыл соединение? 

А у Вас сокет синхронный или ассинхронный? Если синхронный, то, простите, из recv Вы не вернётесь, пока удалённая сторона не пришлёт что-нибудь или не закроет сокет, вот так)))

Это сообщение отредактировал(а) feodorv - 19.11.2013, 19:55


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
ivsh
Дата 19.11.2013, 21:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата

А у Вас сокет синхронный или ассинхронный? Если синхронный, то, простите, из recv Вы не вернётесь, пока удалённая сторона не пришлёт что-нибудь или не закроет сокет, вот так)))

feodorv, да, сокет синхронный, в цикле что-то не заработало)
Да, я понял, что нужно асинхронно сделать. У меня суть задачи, помимо того, что я принимаю данные от пользователя, мне нужно ему отправлять другие данные, через один сокет.
Приложение работает как веб-сервер, принимает от браузера запрос на открытие веб-сокета, а затем шлет ему данные через него, и браузер также отправляет данные через этот же веб-сокет.
То есть открыли сокет, установили соединение, далее слушаю сокет, если есть запросы через него, то обрабатываю запрос и отсылаю результат, если нет, то шлю стандартные данные. Как мне реализовать это?
PM MAIL   Вверх
feodorv
Дата 20.11.2013, 23:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 10
Всего: 45



Цитата(ivsh @  19.11.2013,  22:24 Найти цитируемый пост)
далее слушаю сокет, если есть запросы через него, то обрабатываю запрос и отсылаю результат, если нет, то шлю стандартные данные

Задача не понятна. если нет, то шлю стандартные данные - куда? кому? через прослушиваемый сокет???


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
ivsh
Дата 21.11.2013, 07:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



feodorv, уже разобрался. Ответ нашел в книге "Программирование на С++ глазами хакера". Пробую.
PM MAIL   Вверх
akizelokro
Дата 6.1.2014, 16:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Крокодил
**


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

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



Некоторые люди "засаживают" recv в новый поток.
Есть ещё, кажисть, в WinSock такая фича как установка таймаута для сокета на чтение.

Долго праздновал, все "интересные" (где хоть что-то не совсем глупое могу написать) пропустил. Не дело это!  smile 


--------------------
a = a + b; b = a - b; a = a - b;
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Сети | Следующая тема »


 




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


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

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