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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Концепция любого класса для работы с winsock 
:(
    Опции темы
En_t_end
Дата 15.10.2005, 17:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Занимаюсь разработкой класса инкапсулирующего возможности winsocket'ов. Нужно добиться подобной абстракции:
Псевдокод:
Код

WPsocket wpsock(IP, PORT);
wpsock >> buffer;
wpsock << buffer;

Где >> и << операторы отправки и примема данных соотвественно.
То есть мне надо достичь потоковой гибкости и простоты.
Просто мысли разбегаются... вообще как примерно должен выглядеть такой класс ? Если можно, то в общих чертах.
PM MAIL ICQ Skype GTalk Jabber   Вверх
Mad
Дата 15.10.2005, 18:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Эксперт
Сообщений: 656
Регистрация: 18.10.2004
Где: Одесса

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



En_t_end
В общих чертах так:
создаеш класс
перегружаеш << операторы для него, в которых делаеш send по длине параметра (для данных переменной длины надо добавить какойто разделитель
перегружаеш >> опрераторы в которых делаеш recv пока не будет данных нужной длинны



--------------------
user posted image
PM MAIL   Вверх
En_t_end
Дата 15.10.2005, 18:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Mad
Цитата(Mad @ 15.10.2005, 22:05)
опрераторы в которых делаеш recv пока не будет данных нужной длинны

В смысле ?... это что перебор получается ? smile
Добавлено @ 18:17
Цитата(Mad @ 15.10.2005, 22:05)
перегружаеш >> опрераторы в которых делаеш recv пока не будет данных нужной длинны

В том-то и проблема, что я не знаю какие данные должны прийти. Вернее я то знаю, обьект класса не знает.
Есть мысля по этому поводу...
Код

wpsock.SetDataSize(HOW_LONG_DATA);
wpsock >> buffer;

То есть так можно будет скрыть от программиста цикл приема данных по частям.

PM MAIL ICQ Skype GTalk Jabber   Вверх
Mad
Дата 15.10.2005, 18:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Эксперт
Сообщений: 656
Регистрация: 18.10.2004
Где: Одесса

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



Цитата(En_t_end @ 15.10.2005, 17:14)
это что перебор получается

нет, например
Код

public operator >> (int& val)
{
    char buff[4];
    recv(sock, buff, 4, 0);
    val = *(int*)buff;
}

также и для других типов данных(только надо еще добавить проверку саколько принято smile)


--------------------
user posted image
PM MAIL   Вверх
En_t_end
Дата 15.10.2005, 18:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Mad
Есть ещё проблема с размерами сетевых пакетов для протокола TCP/IP.
Нужно каким-то образом точно разбить данные(скорее всего придется узнавать максимально возможный размер пакета, кстати как это можно сделать, как можно переносимей для винды) и отправить их по средством << настолько чисто, так чтобы для программиста, пользующегося обьектом, все это выглядело в одной операции.
PM MAIL ICQ Skype GTalk Jabber   Вверх
Mad
Дата 15.10.2005, 18:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Эксперт
Сообщений: 656
Регистрация: 18.10.2004
Где: Одесса

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



Цитата(En_t_end @ 15.10.2005, 17:14)
В том-то и проблема, что я не знаю какие данные должны прийти. Вернее я то знаю, обьект класса не знает.

Если в приведенном мной коде добавить контроль поступления
Код

char buff[4];
int received = 0;
while(received < 4)
{
    int i = recv(sock, buff+received, 4-received, 0);
    received += i;
}

тогда у тебя оператор выйдет только после получения 4 байтов (т.е полно int как и нужно было smile)

Цитата(En_t_end @ 15.10.2005, 17:22)
Нужно каким-то образом точно разбить данные

а зачем ? TCP и так дает полный поток. Если в самом операторе ждать получения полных данных, то уже без разницы как там TCP этиданный разбила (тем более, что они могут быть дополнительно разбиты при пересылке роутером)


--------------------
user posted image
PM MAIL   Вверх
En_t_end
Дата 15.10.2005, 18:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Mad
ОК... спасибо... будем работать
Добавлено @ 18:38
Цитата(Mad @ 15.10.2005, 22:30)
а зачем ? TCP и так дает полный поток.

Просто я сам был свидетелем работы одной программы сделанной для отмазки. Там наблюдался глюк с приемом и отправкой большого обьема данных. Получалось, что данные приходили либо не полностью, либо вовсе не приходили.
Мое беспокойство было вызванно именно по поводу отправки... система сама разбивает данные ?
ЗЫ просто сам я кроме больше чем 100 байт через TCP/IP не передовал.
PM MAIL ICQ Skype GTalk Jabber   Вверх
bel_nikita
Дата 15.10.2005, 18:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Эксперт
Сообщений: 2304
Регистрация: 12.10.2003
Где: Поезд №21/22 ( ст . Прага )

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



En_t_end
Что-то подобное реализовывал 2 года назад.
Можно сделать, что данные в буфер кладутся в течении 50 мсек, а потом отсылаются. И так же контроль буфера, т.е. если буфер полон - данные отсылаются.
Также можно ввести идентификаторы:
Код
 
class CBaseSock{
...
public:
  enum Ident{ START, FLUSH, SIZE, DATA, STOP };
...
  template<class T> CBaseSock& operator << (T tData)
  {
      if ( isChild(tData) )
     {
      ...
      // Если tData - тип Ident::SIZE, то значит в tData придет размер данных
     }
     ...
  }
...
};



--------------------
user posted image — регистрация доменов от 150 руб.
PM MAIL WWW ICQ   Вверх
Mad
Дата 15.10.2005, 18:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Эксперт
Сообщений: 656
Регистрация: 18.10.2004
Где: Одесса

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



Цитата(En_t_end @ 15.10.2005, 17:33)
Получалось, что данные приходили либо не полностью, либо вовсе не приходили.

При отправке (вызове send) возвращаеться сколько данных помещенно в буффер, с контролем получаеться так
Код

void SendData(char *buff, int len)
{
    int sended = 0;
    while(sended < len)
    {
        int i=send(sock, buff+sended, len-sended, 0);
        sended += i;
    }
}

так я максимум до 20Мб пересылал


--------------------
user posted image
PM MAIL   Вверх
En_t_end
Дата 16.10.2005, 08:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Mad
Thks!
bel_nikita
Очень интересное предложение, попробую реализовать.
PM MAIL ICQ Skype GTalk Jabber   Вверх
En_t_end
Дата 16.10.2005, 08:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



bel_nikita
Насколько я понимаю, если расширить ваш совет, то можно будет добиться следующей абстракции:
Код

wpsock << DATA_SIZE << buffer;


PM MAIL ICQ Skype GTalk Jabber   Вверх
Mad
Дата 16.10.2005, 12:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Эксперт
Сообщений: 656
Регистрация: 18.10.2004
Где: Одесса

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



Цитата(En_t_end @ 16.10.2005, 07:44)
wpsock << DATA_SIZE << buffer;

Это уже зависит от того, какие именно данные ты собираешся пересылать
например, если у тебя по сокету идут только структуры фиксированной велечины, и в строгом порядке, то пересылка их размера просто увеличит обьем генерируемого трафика, ез какойто выгоды
а вот если ты будеш пересылать бинарные данные различной длины (напримерjpeg файлы smile) то без пересылки размера вообще не обойтись

TCP предоставляет только транспорт, протокол обменна клиент<->сервер(протокол высокого уровня) надо разрабатывать самому


--------------------
user posted image
PM MAIL   Вверх
bel_nikita
Дата 16.10.2005, 18:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Эксперт
Сообщений: 2304
Регистрация: 12.10.2003
Где: Поезд №21/22 ( ст . Прага )

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



En_t_end
Цитата
Насколько я понимаю, если расширить ваш совет, то можно будет добиться следующей абстракции

Да, именно так.
Код

 wpsock << DATA_SIZE << LenghtBuffer << pBuffer; 

Хотя это уже разновидности реализации на усмотрение разработчика.
Вообще, хорошо бы разбить все на уровни: транспортный, пакетный и пользовательский. Транспортный(физический) только непостредственно прием/передача. Пакетный - создание пакетов для отсылки или распаковка при приеме. Пользовательский или сервисный уровень - это и есть перегрузка операторов << >>.
Так же хорошо(как и говорил выше) сделать отдельный тред на отсылку, или другими словами таймер. Как только первая порция(назавем так) данных поступипа - включается таймер и данные кладуться в буфер. Как только прошло допустим 50 мсек или в буфере нет уже места - данные отсылаются. Ну и конечно, предусмотреть идентификатор FLUSH - отсылка/очистка буфера, т.е. данные сразу отсылаются без таймера.
Ну и конечно, нужно знать для чего это все нужно? Если это файлы, то тут лучше использовать FTP. Если какие-то большие объемы информации, то обязательно нужно реализовывать пакетный уровень. Ведь в TCP первый высланный пакет может прийти последним smile


--------------------
user posted image — регистрация доменов от 150 руб.
PM MAIL WWW ICQ   Вверх
En_t_end
Дата 17.10.2005, 11:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



bel_nikita
Цитата(bel_nikita @ 16.10.2005, 22:56)
Ведь в TCP первый высланный пакет может прийти последним 

То есть надеется на последовательное заполнение буфера в цикле recv не стоит ?
Добавлено @ 11:10
Пока делаю так...
Создал класс родитель LSocket:
Код

class LSocket
{};

И два потомка:
Код

class LSockAccept : public LSocket
{};

class LSockJoin : public LSocket
{};

Теперь реализую в потомке Accept сокет переводящийся в режим ожидания подключения.
А для Join - организацую подключения со стороны клиента.

Подумываю организовать специальный протокол обмена. То есть обеспечить автоматическое выделение канала FTP для передачи файлов, если будет получен соотвествующий запрос по TCP.
PM MAIL ICQ Skype GTalk Jabber   Вверх
Mad
Дата 17.10.2005, 12:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Эксперт
Сообщений: 656
Регистрация: 18.10.2004
Где: Одесса

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



Цитата(En_t_end @ 17.10.2005, 10:01)
Ведь в TCP первый высланный пакет может прийти последним

smilesmilesmile откуда такая инфа ? smilesmilesmile


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


 




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


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

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