Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: 1 2 3 [Все]   Вниз
  Печать  
Автор Тема: сбор данны по сети  (Прочитано 100596 раз)
0 Пользователей и 2 Гостей смотрят эту тему.
locator
Постоялец

ru
Offline Offline

« : 09-06-2013 13:33 » 

Доброго времени суток! есть девайс, собирающий данные (на шине PC/104), сам компьютер PC/104 соединен
через wi-fi с ноутбуком. Девайс формирует данные в виде пакетов размером около 600 байт. Интервал обновления
пакетов около 1мс (частота 1кГц). Задача в том, чтобы посылать пакеты в ноут с максимальной скоростью
(которую позволяет соединение wi-fi 50мбит/c). Я создал сервер, и тупо написал поток передачи пакетов клиенту,
вот потоковая функция:
Код: (C++)
DWORD WINAPI SendData(LPVOID client_socket)
  {
    SOCKET my_sock;
    my_sock = ((SOCKET *)client_socket)[0];
        union
        {
                DEV_DATA dat; // структура данных от девайса рамером 600 байт
                char buff[sizeof(DEV_DATA)];
        };
        while(1)
        {  
           send(my_sock, buff, sizeof(DEV_DATA), 0);
           Sleep(10); // задаю 100 раз в секунду передачу пакетов
        }
    return 0;
  }
Но клиент на ноутбуке принимает битые пакеты или вообще зависает (писал с
компонентом TClientSocket на билдере). Задал интервал передачи в потоке 5 раз
 в секунду (написал Sleep(200)), все нормально передается. Я так понимаю, что
пакеты можно намного чаще передавать, чем 5  раз в секунда. Как мне грамотно
написать процесс передачи/приема пакетов (так, чтобы скорость обмена была максимальной) ? 
В инете про это никто  не пишет (все статьи о том, как соединить сервер с клиентом,
 не более того  Здесь была моя ладья...).  Может ссылки полезные дадите?   
На PC/104 установлена winxp, на ноуте win7.
Спасибо за ответы!
« Последнее редактирование: 09-06-2013 14:02 от locator » Записан
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 09-06-2013 14:32 » 

Ну... тут скорей нужна математика.

50Мбит/с ~ 5Мб/с

делим на 600, получаем 8000 пакетов в сек

зы... я не ошибся в расчетах?
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
locator
Постоялец

ru
Offline Offline

« Ответ #2 : 09-06-2013 16:07 » 

немного ошибся, в пакет добавляется заголовок ip, поэтому скорость
поменьше будет. и как это реализовать?
Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #3 : 09-06-2013 16:11 » 

А собрать несколько пакетов в обший пакет?
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
locator
Постоялец

ru
Offline Offline

« Ответ #4 : 09-06-2013 17:16 » 

а это как?
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #5 : 09-06-2013 18:32 » 

locator, с позиции API сокетов пофиг, посылаешь ли ты по гигабитному ethernet, через WiFi или по модему на 1200 бод: интерфейс один и тот же. Битых пакетов программа получить не может. Пакет либо будет получен целиком, либо не будет получен совсем. Напрашивается вывод, что у тебя ошибка в программе (в какой — тебе виднее, код мы не видим).

Подмечу, что упрощенная формула, применяемая к ethernet (байт/с = бит/с ÷ 10), в WiFi не работает. Фактическая скорость передачи будет зависеть от множества факторов, предсказать которые заранее невозможно. Это сеть с негарантированной пропускной способностью. Кстати, служебные данные WiFi передаются на скоростях 1 или 2 Мбит/с, а с большими скоростями передается полезная нагрузка (в данном случае IP-пакеты). Т.к. WiFi — сеть с разделяемой средой передачи, то возможны коллизии и есть переменная задержка начала передачи (и повторной передачи пакета).  Еще есть подтверждение приема пакета. При работе через точку доступа пакет проходит по эфиру дважды. В общем, протокол сложен и для оценки приблизительной максимальной скорости стоит делить не на 10, а на 25. А есть и еще понижающие скорость факторы: загрузка эфира (разделение частотного канала разными пользователями WiFi), помехи (возможны повторные пересылки и понижение скорости передачи).
Для точного расчета задержек передачи нужно углубляться в чтение стандартов. Попробую очень грубо прикинуть...
Скажем, на скорости 54 Мбит/с блок данных в 600 байт (плюс 28 байт на заголовки IP и UDP) передастся за ≈93 мкс. Накинем на служебные нужды: пусть получится порядка 150 мкс. Двойной проход по эфиру: уже 300 мкс. Два подтверждения получения пакета, задержки, помехи, коллизии: 1000 пакетов в секунду — это оптимистичный прогноз, хотя и достижимый при должных условиях. Куда производительнее будет собирать данные в буфер и пересылать более крупными партиями.
« Последнее редактирование: 09-06-2013 18:42 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
locator
Постоялец

ru
Offline Offline

« Ответ #6 : 09-06-2013 19:09 » 

ну какая может быть ошибка, все копировалось с известных программ:
Код: (C++)
int nclients = 0;

 while((client_socket = accept(mysocket, (sockaddr *)&client_addr, &client_addr_size)))
        // цикл извлечения запросов на подключение из очереди клиентов
    {
       nclients++;

      HOSTENT *hst;

      hst = gethostbyaddr((char *)&client_addr.sin_addr.s_addr, 4, AF_INET);
   
     DWORD thID;
      CreateThread(NULL, NULL, SendData,  &client_socket, NULL, &thID);

      if(nclients == 1) break; // нам больше одного клиента не надо
    }


// функция сервера (передает пакеты)
DWORD WINAPI SendData(LPVOID client_socket)
  {
    SOCKET my_sock;
    my_sock = ((SOCKET *)client_socket)[0];
        union
        {
                DATA data;
                char buff[sizeof(DATA)];
        };

        while(1)
        {  
           send(my_sock, buff, sizeof(DATA), 0);
           Sleep(10);
        }
 
    return 0;
  }

// функция клиента
void __fastcall TForm1::ClientSocket1Read(TObject *Sender,
      TCustomWinSocket *Socket)
{
 
  if(ClientSocket1->Active == false) return;

  int len = Socket->ReceiveLength(); // получили длину пакета
//если более 5 раз/с передача, то длина получается любой, 1000 байт, 2000 байт... (почему ?????)

  char *Buff = new char[sizeof(DATA)];

  AnsiString s; s.SetLength(len);

  Socket->ReceiveBuf(Buff, len);

  strcpy(data, Buff); // массив data объявлен глобальным
}

Кстати, если весь обмен тестировать на локальном компе, то все летает..... действительно около 1000 раз/с.
Я просто не понимаю, как передаются данные, например, фильмы, музыка по сетевым протоколам....? Видимо, как-то
по другому,  а как?


Добавлено через 2 минуты и 32 секунды:
Finch, двинь идейку пожалуйста  Улыбаюсь
« Последнее редактирование: 09-06-2013 19:11 от locator » Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #7 : 09-06-2013 19:30 » 

locator, у тебя сокеты UDP или TCP?

А программа — ужас.
« Последнее редактирование: 09-06-2013 19:33 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
locator
Постоялец

ru
Offline Offline

« Ответ #8 : 10-06-2013 03:58 » 

сокеты TCP конечно
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #9 : 10-06-2013 04:21 » 

locator, когда мне встречалась такая задача, самый действенный вариант каждый раз оказывался такой:
запускается несложного содержания поток считывания, работающий максимально быстро (понадобится ознакомиться с описанием функций timeGetDevCaps , timeBeginPeriod , CreateEvent ,WaitForSingleObject )

поток имеет некоторый не сильно большой приёмный буфер (килобайты) . Одна итерация запрашивает (методом receive) из сокета данные размером с этот буфер, и всё, что считалось, через синхронизатор (критическая секция) дописывает во внешний приёмный буфер (бОльших размеров). Затем производится ожидание в 1 мс - сбрасывается созданный для этих целей хендл события и вызывается WaitForSingleObject  для него, затем идёт новая итерация

Таким образом во внешнем буфере имеем актуальный поток данных, разгружая при этом сокет и не допуская потерь на этом уровне). При работе с внешним буфером, через тот же синхронизатор вытаскиваем порцию данных (копируем и разлочиваем, собственно, чтобы не затормаживать поток) и дальше "спокойно" анализируем.

Не претендую на идеальность способа, но он работает )

Всё то же самое будет работать и с UDP

Добавлено через 2 минуты и 35 секунд:
данные, передаваемые по wi-fi лучше, конечно же, собирать в пакеты. Попробуй ещё и сжимать , если скорость не устроит
« Последнее редактирование: 10-06-2013 04:24 от Алексей++ » Записан

locator
Постоялец

ru
Offline Offline

« Ответ #10 : 10-06-2013 05:24 » 

значит, тотальная буферизация нужна.
Известно, что у компонента TClientSocket есть поток встроенный.
Алексей++, это случайно не тот поток, о котором ты говоришь?
И еще я не понимаю: на передатчике пакетов должен стоять сервер
или клиент? Или это без разницы?
Записан
darkelf
Молодой специалист

ua
Offline Offline

« Ответ #11 : 10-06-2013 05:26 » 

locator, а что Вы понимаете под "битыми" пакетами? Как правильно сказал RLX в tcp/ip и udp/ip пакет битым прийти не может, его должны отфильтровать на протокольном уровне - там контрольные суммы передаются. Могут быть потери, если используете udp, и это значит, что, скорее всего, Вы не успеваете забирать сообщения из сокета. В качестве варианта - можно попробовать увеличить буфера приёма через setsockopt(fd, .., SO_RCVBUF,..), но более правильным будет вариант, который тут предложили - попробовать объединить пакеты, т.е. за раз выдавать информацию не одного пакета, а двух, но зато с вдвое меньшей частотой.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #12 : 10-06-2013 05:39 » 

locator, мне неизвестно, что есть в TClientSocket , я билдером не пользовался. В самой WinAPI при создании сокета вроде никаких потоков не создаётся.

Сервер должен стоять на сервере (на приёмнике) - он нужен для принятия подключения от клиента в случае TCP. Но уже в передаче и приёме данных сервер никак не участвует
Записан

sss
Специалист

ru
Offline Offline

« Ответ #13 : 10-06-2013 05:41 » 

locator, а что Вы понимаете под "битыми" пакетами? Как правильно сказал RLX в tcp/ip и udp/ip пакет битым прийти не может,

Может. Две последовательные передачи могут быть приняты одновременно или даже разрезаться по неравным частям.
Например:

Передаём три раза по 600 байт.
Варианты приёма:
1) Три раза по 600 байт.
2) Один раз 1800 байт
3) 1500 + 300
..

Надеюсь проблема понятна.

P.S.: Для TCP сокета можно ещё выключить алгоритм Нагла (Nagle).

« Последнее редактирование: 10-06-2013 05:43 от sss » Записан

while (8==8)
locator
Постоялец

ru
Offline Offline

« Ответ #14 : 10-06-2013 06:02 » 

locator, а что Вы понимаете под "битыми" пакетами?  
я смтотрю длину пакета функцией Socket->ReceiveLength(), и длина все время разная
получается (1000, 2000 байт). Получается, что пакет не принят. Или сразу два пакета
прилетело.
« Последнее редактирование: 10-06-2013 06:03 от locator » Записан
darkelf
Молодой специалист

ua
Offline Offline

« Ответ #15 : 10-06-2013 06:10 » 

locator, а что Вы понимаете под "битыми" пакетами? Как правильно сказал RLX в tcp/ip и udp/ip пакет битым прийти не может,

Может. Две последовательные передачи могут быть приняты одновременно или даже разрезаться по неравным частям.
Например:

Передаём три раза по 600 байт.
Варианты приёма:
1) Три раза по 600 байт.
2) Один раз 1800 байт
3) 1500 + 300
..

Надеюсь проблема понятна.

P.S.: Для TCP сокета можно ещё выключить алгоритм Нагла (Nagle).
В TCP нет понятия пакетов, там - поток, соответственно данные могут хоть по байту приходить - если их правильно принимать (например использовать в recv() флаг MSG_WAITALL в unix-подобных ОС, или просто дочитывать до требуемой длины в win), то таких проблем быть не должно. При этом битых пакетов всё-равно быть не может - сообщение либо приходит, либо нет, в tcp/ip если не было подтверждения о получении, то сообщение будет выслано повторно, в udp хуже - просто выбросят и всё.  А про алгоритм Нагла Вы правильно сказали - в данной ситуации может немного помочь.
Записан
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #16 : 10-06-2013 06:11 » 

Я повторю вопрос.

По скорости все согласовано?
Успеваешь передавать пакеты?
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
darkelf
Молодой специалист

ua
Offline Offline

« Ответ #17 : 10-06-2013 06:12 » 

locator, в tcp нет пакетов. Вам надо не просто принимать сообщения, а ещё их правильно собирать.
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #18 : 10-06-2013 06:15 » 

сокеты TCP конечно

Тогда для буферизации ничего делать не надо. Алгоритм отложенной отправки сам решит, когда отправлять очередной пакет. А для API TCP сокет представлен как поток байт, а не набор пакетов. Соотв., тебе нужно структуировать данные, чтобы можно было понять начало и конец блока данных. Например, так:

Код: (C++)
typedef struct _packet_buffer{
    uint16 size;
    DEV_DATA dat;
    void _packet_buffer(void) {
        size = sizeof(_packet_buffer);
    };
} packet_buffer_t;

// ...
packet_buffer_t buffer;

//...
send(socket, (void *)&buffer, sizeof(packet_buffer_t), 0);

При приеме считать sizeof(uint16) байт, после чего считать указанное число байт. Если объем считанных данных недостаточен, значит надо повторить считывание (обычных блокируемый ввод-вывод решает эту проблему).

Добавлено через 5 минут и 45 секунд:
locator, а что Вы понимаете под "битыми" пакетами? Как правильно сказал RLX в tcp/ip и udp/ip пакет битым прийти не может,

Может. Две последовательные передачи могут быть приняты одновременно или даже разрезаться по неравным частям.
Например:

Передаём три раза по 600 байт.
Варианты приёма:
1) Три раза по 600 байт.
2) Один раз 1800 байт
3) 1500 + 300
..

Надеюсь проблема понятна.

P.S.: Для TCP сокета можно ещё выключить алгоритм Нагла (Nagle).

Это не «битые пакеты», а невыровненные данные. Потому как потоки и пакеты — разные концепции.
« Последнее редактирование: 10-06-2013 06:28 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
locator
Постоялец

ru
Offline Offline

« Ответ #19 : 10-06-2013 06:23 » 

то бишь читать по одному байтику из принимаемого потока, и разделять
заголовки пакетов?
Или функцией Socket->ReceiveBuf(Buff,len) складывать буферы Buff в другой
большой буфер (или очередь), и уже оттуда анализировать цепочку байтов
(отделять заголовки пакетов)?
« Последнее редактирование: 10-06-2013 06:26 от locator » Записан
darkelf
Молодой специалист

ua
Offline Offline

« Ответ #20 : 10-06-2013 06:26 » 

locator, зачем побайтно? Читать по столько, по сколько читается, просто написать алгоритм разбора, например конечный автомат.
Или функцией Socket->ReceiveBuf(Buff,len) складывать буферы Buff в другой
большой буфер (или очередь), и уже оттуда анализировать цепочку байтов
(отделять заголовки пакетов)?
можно и так.
« Последнее редактирование: 10-06-2013 06:27 от darkelf » Записан
sss
Специалист

ru
Offline Offline

« Ответ #21 : 10-06-2013 06:26 » 


Это не «битые пакеты», а невыровненные данные. Потому как потоки и пакеты — разные концепции.


Человек передаёт и ожидает пакеты через поток TCP. В TCP нет пакетов? Есть(!) - используются для организации потока.. И вообще - есть связь с установлением соединения и без установления соединения. 
« Последнее редактирование: 10-06-2013 06:29 от sss » Записан

while (8==8)
darkelf
Молодой специалист

ua
Offline Offline

« Ответ #22 : 10-06-2013 06:28 » 

sss, на прикладном уровне, на котором работает человек - пакетов нет, как нет секторов при работе с диском.
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #23 : 10-06-2013 06:29 » 

locator, перечитай пост, я его дополнил примером.
https://forum.shelek.ru/index.php/topic,29445.msg289155.html#msg289155

Добавлено через 3 минуты и 55 секунд:

Это не «битые пакеты», а невыровненные данные. Потому как потоки и пакеты — разные концепции.


Человек передаёт и ожидает пакеты через поток TCP. В TCP нет пакетов? Есть(!) - используются для организации потока.. И вообще - есть связь с установлением соединения и без установления соединения. 

Чушь говоришь, дорогой. Ты приравниваешь программный буфер отправки к транспортному пакету и программному буфер приема, да еще для протокола, не гарантирующего пакетную разбивку. Отправь 600 байт по сети с TCP MSS равным 400!
« Последнее редактирование: 10-06-2013 06:33 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
sss
Специалист

ru
Offline Offline

« Ответ #24 : 10-06-2013 06:33 » 

sss, на прикладном уровне, на котором работает человек - пакетов нет, как нет секторов при работе с диском.
Блин где Вы взяли что TCP поточный, а UDP пакетный? Ещё раз - есть связь с установлением соединения и без установления соединения.  
Все протоколы используют пакеты..
Записан

while (8==8)
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #25 : 10-06-2013 06:36 » 

sss, личные убеждения — это святое, но не при обмене информацией. Поднимись над IP и углубись в API.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
locator
Постоялец

ru
Offline Offline

« Ответ #26 : 10-06-2013 06:37 » 

из сказанного выше, я понял что передаваемые мной данные система
делит на блоки и передает эти блоки, причем размером блоков я уже
не могу управлять.  За одну посылку пакета 600 байт передаться может как
600, так и 400 байт, тогда остаток принимается уже в следующий прием.
Записан
sss
Специалист

ru
Offline Offline

« Ответ #27 : 10-06-2013 06:38 » 

RXL, вот что я знаю - есть сети с коммутацией пакетов и коммутацией каналов. Хотите поговорить об этом? Или это мои личные убеждения?

Добавлено через 2 минуты и 44 секунды:
А вот нашёл - Протокол не сохраняющий границы сообщений, обычно называют протоколом, основанном на потоке.
« Последнее редактирование: 10-06-2013 06:41 от sss » Записан

while (8==8)
darkelf
Молодой специалист

ua
Offline Offline

« Ответ #28 : 10-06-2013 06:44 » 

sss, имхо, Вы немного путаете, как оно реализовано "внизу" и какой интерфейс имеет "вверху". То, что там бегают пакеты никак не влияет на его интерфейс с верхом, а этот интерфейс таков, что предоставляется поток данных, без разбиения на пакеты - можете хоть побайтно вычитывать - если будете успевать - всё будет работать и данные теряться не будут. Ещё раз приведу аналогию с жестким диском - там внутри сектора, на уровне ФС - блоки и кластеры, но тем не менее, когда Вы работаете через интерфейс ОС типа read()/write() - Вас это как-то мало волнует - для Вас это просто поток байтов, хотя физически он там может быть очень неплохо быть разбросанным по диску..
« Последнее редактирование: 10-06-2013 06:46 от darkelf » Записан
sss
Специалист

ru
Offline Offline

« Ответ #29 : 10-06-2013 06:46 » 

из сказанного выше, я понял что передаваемые мной данные система

Вам придётся передавать пакеты через поток. Вначале - длина пакета, затем данные.  На приёмной стороне парсить.. Иначе это всё лишь предположения и танцы с бубнами.. Это очень вылезет на дальнем расстоянии в условиях больших задержек пакетов на маршрутизаторах.. Там будут абсолютно непредсказуемые буферы приходить.. Но зато всегда по порядку
Записан

while (8==8)
sss
Специалист

ru
Offline Offline

« Ответ #30 : 10-06-2013 06:51 » 

как-то мало волнует - для Вас это просто поток байтов

Файл это поток структурированных данных - при чтении я их последовательно изучаю и в зависимости от прочитанных данных выполняю некоторые действия. А в случае TCP - я читаю столько, сколько дадут - поэтому еще более важна логика чтения!
Записан

while (8==8)
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #31 : 10-06-2013 06:52 » 

Могу только порекомендовать для этого modbus внутри tcp

Блок данных запихивать во фрейм modbus, на приемной стороне раскрывать
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
sss
Специалист

ru
Offline Offline

« Ответ #32 : 10-06-2013 06:55 » 

Sla, не знаю - я использую посылку длины, а на приёмной стороне цепочка буферов... По мере наполнения буферов я их выдаю приёмной стороне..
Записан

while (8==8)
locator
Постоялец

ru
Offline Offline

« Ответ #33 : 10-06-2013 06:56 » 

разбор потока байтов наверное проще будет сделать, чем во фрейм запихивать
Записан
sss
Специалист

ru
Offline Offline

« Ответ #34 : 10-06-2013 06:59 » 

Да это логично, а значит проще всего. И если поток постоянный/скоростной не выключай Nagle - быстрее будет.
Ну и плюс попробуй использовать порты завершения - чрезвычайно мощная вещь.
« Последнее редактирование: 10-06-2013 07:01 от sss » Записан

while (8==8)
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #35 : 10-06-2013 07:05 » 

по сути модбас это цепочка байт
фрейм подразумевает, что данные находятся внутри

А если по сети будет идти обмен с несколькими девайсами? Это только сейчас один.

Кроме того, сервер, который собирает эти данные может получать данные и лот других источников, по 485, например.

Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
darkelf
Молодой специалист

ua
Offline Offline

« Ответ #36 : 10-06-2013 10:17 » 

как-то мало волнует - для Вас это просто поток байтов

Файл это поток структурированных данных - при чтении я их последовательно изучаю и в зависимости от прочитанных данных выполняю некоторые действия. А в случае TCP - я читаю столько, сколько дадут - поэтому еще более важна логика чтения!
Вы не совсем правы, структуру файла знаете Вы, но никак не ОС/ФС, так-что может это для Вас они структурированы, а для системы - нет, аналогично и с сокетами. Если все сообщения у Вас фиксированной длины - ну тогда вычитывать именно эту длину, и пока всё не прочитал - чтения не завершать, будет всё так-же. Т.е. отличие только в том, что read() Вам всегда (я не рассматриваю ошибки и конец файла) вернёт столько байтов, сколько просите, а recv() - нет, но если написать что-то типа:
Код:
int sock_read(int fd, char* p, int len)
{ int r;
  while (len > 0)
  { r = recv(fd, p, len, 0)
     len -= r;
     p += r;
  }
  return len;
}
то, несмотря на всякие потоки, всё будет работать нормально. Разве-что в этот код добавить проверки ошибок.
« Последнее редактирование: 10-06-2013 10:19 от darkelf » Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #37 : 10-06-2013 13:43 » 

В общем, я так понял, что автор темы полагал передавать по сети свои авторские пакеты по 600 байтов прямо по проводам, но проигнорировал весь стек протоколов.

Совет тут только один. Писать в сокет свои пакеты, как пишется - лишь следить, чтобы каждый пакет записывался целиком, и если это не так, пробовать писать до победы. Аналогично читать пакеты из сокета блоками по те же 600 байтов. Если прочитано меньше, пробовать читать дальше до победы. А как оно там по сети ходит, дробится, какими заголовками обвешивается и как гарантируется безошибочность передачи - это вообще автора не касается, и он не в свою тему полез. Только если для общего развития или любопытства ознакомиться без каких-либо последствий для программной реализации передачи.

Останется только следить: а) за скоростью передачи, чтобы пропускная способность каналов была достаточной, и чтобы стороны не тормозили сами по себе; б) обработку ситуации обрыва связи, чтобы стороны не зависали в безуспешных попытках чтения/записи - обычно решается при помощи таймаута, что если, допустим столько-то секунд "не алё", то связь считается оборванной.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
sss
Специалист

ru
Offline Offline

« Ответ #38 : 10-06-2013 13:45 » 

Да я уже не спорю.. Допустим есть такое понятие - потоковое вещание. При этом есть реализации и в UDP и в TCP. Я пытаюсь сказать что есть различие между понятием потоковый и дейтаграммный сокет, а не потоковый и пакетный. В чём разница между вызовом recv на UDP и TCP сокете ? Её нет. Это я про скрытие реализации..
« Последнее редактирование: 10-06-2013 13:50 от sss » Записан

while (8==8)
darkelf
Молодой специалист

ua
Offline Offline

« Ответ #39 : 10-06-2013 14:02 » 

Да я уже не спорю.. Допустим есть такое понятие - потоковое вещание. При этом есть реализации и в UDP и в TCP. Я пытаюсь сказать что есть различие между понятием потоковый и дейтаграммный сокет, а не потоковый и пакетный. В чём разница между вызовом recv на UDP и TCP сокете ? Её нет. Это я про скрытие реализации..
там "потоковое" это, имхо, немного другое "потоковое", чем здесь.
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #40 : 10-06-2013 16:00 » 

sss, признаться, я вообще не понимаю о чём ты говоришь. Это как пытаться рассуждать о том, что свёкла - это не морковка, хотя обе - корнеплоды. И что с того?
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
sss
Специалист

ru
Offline Offline

« Ответ #41 : 11-06-2013 01:43 » 


признаться, свёкла - это не морковка. И что с того?

Хотите прекратить досужие споры переведя тему в плоскость философии? Я бы рад, но увольте. Попробую остаться в плоскости сетей.

 - Ответьте на вопрос почему вначале темы возникли вопросы - сокет UDP или TCP?
 - Потому что в контексте вызова на сокете нет разницы какой он - назовём это сокрытием реализации.
 - Ура! Сокрытие реализации поточной передачи! Тогда почему я не могу рассматривать передачу как пакетную передаваемую через поток?
 - Потому что это TCP.
 - Так ведь TCP использует пакеты (FIN, ACK, RST)?
 - Это сокрытие реализации.

Заколдованный круг рассуждений. Я как раз предлагаю не заострять внимание на терминах и не считать одним и тем же понятие - пакет и дейтаграмма!


Записан

while (8==8)
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #42 : 11-06-2013 06:29 » 

Ну и сам же ушел в философию... Улыбаюсь
Давай говорить сухо и по делу.

1. Протоколы TCP и UDP представляют две разные транспортные концепции: байтовый поток и дейтаграмма.
2. В потоке размер IP пакета не коррелирует с размером отсылаемой структуры, но пакет IP включает дейтаграмму целиком.
3. Поток не лимитирован по размеру. Дейтаграммы ограничены реализацией стека протоколов (ограничение может быть в рамках MTU или используется фрагментация большого пакета при отсылке).
4. Для выделения полученной структуры данных в потоке необходимо определять начало и конец или размер этой структуры, в дейтаграмме надо лишь задать достаточный по размеру буфер приема.

Совершенно разный подход!
Не говоря уже о различиях в гарантии доставки.

Если в чем сомневаешься, штудируй Стивенсона. Если не сомневаешься — тем более штудируй. Попутно не забывай про Winsock.

« Последнее редактирование: 11-06-2013 06:31 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
sss
Специалист

ru
Offline Offline

« Ответ #43 : 11-06-2013 07:06 » 

Между прочим, теперь в твоих формулировках вообще не вижу ничего спорного. Пакеты для создания гарантированных потоков, пакеты же для создания потока дейтаграмм и пакетирование для выявления полученных структур - другой способ маркеры конца. Получив очередной буфер вне зависимости от транспорта хочу иметь право говорить - парсинг принятого пакета. А вы мне категорично это запрещаете - говорите в TCP нет пакетов. Вообще можно вообще ответить - при чём здесь TCP? TCP только транспорт!
Например службы DNS - пожалуйста хотите используйте UDP или TCP но доставляют они пакеты DNS!

P.S.: Опять скажут что сравниваю что то не то. Жаль

Добавлено через 5 минут и 42 секунды:
Тут вообще как всё началось - кто то сказал что использует TCP и при этом портятся данные (логические пакеты пользователя). Ему ответили - TCP не бьёт пакеты и вообще там нет пакетов и понеслась...  А я пытаюсь сказать, что TCP выполняет огромную работу по транспорту при этом не гарантируя (внимание) соблюдения границ сообщений пользователя (логических пакетов пользователя).
« Последнее редактирование: 11-06-2013 07:14 от sss » Записан

while (8==8)
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #44 : 11-06-2013 07:19 » 

Э... не путайте ТС

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

И вот он отдает свой блок данных,  а отправитель, чтоб не растрачивать ресурсы и не гонять порожняком ждет еще данных.
Когда времени хватает (с задержкой) то носитель, не дождавшись уже уехал и привез 600байт.
А вот когда все время идет пересылка,  то его данные разбиваются, а получатель об это не знает, и говорит, что посылка битая.

зы мне кажется такое видение.
Как заставить транспорт передать только один пакет получателю?
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
darkelf
Молодой специалист

ua
Offline Offline

« Ответ #45 : 11-06-2013 07:22 » 

И вот он отдает свой блок данных,  а отправитель, чтоб не растрачивать ресурсы и не гонять порожняком ждет еще данных.
Когда времени хватает (с задержкой) то носитель, не дождавшись уже уехал и привез 600байт.
А вот когда все время идет пересылка,  то его данные разбиваются, а получатель об это не знает, и говорит, что посылка битая.

зы мне кажется такое видение.
Как заставить транспорт передать только один пакет получателю?
там проблема не только в передаче, а и в приёме. Причем если правильно организовать приём, то как там оно передаёт уже особо не важно.
Записан
sss
Специалист

ru
Offline Offline

« Ответ #46 : 11-06-2013 07:23 » 

Как заставить транспорт передать только один пакет получателю?

Тут можно выключить Nagle. Только не поможет если много маршрутизаторов на пути. Придут, например, по 100 + 100 + 400
Вот не знаю - дейтаграммы сегментируются или нет? Думаю молча отбрасываются если не влезают..
Записан

while (8==8)
locator
Постоялец

ru
Offline Offline

« Ответ #47 : 11-06-2013 07:34 » 

однако, в сети глубоко залезешь - обратно не вылезешь  Улыбаюсь
прилепил в начале своей структуры заголовок, на приемной
стороне все буферы собираются в цепочку - все ок, все пакеты
нормально принимаются.  Получилось примерно 35 раз/сек.
А ускорить никак нельзя ? Можно поподробнее про настройку Nagle?
Записан
sss
Специалист

ru
Offline Offline

« Ответ #48 : 11-06-2013 07:42 » 

Что то очень медленно. Какой на передающей стороне код ?

Про Nagle смотри опцию TCP_NODELAY

http://msdn.microsoft.com/en-us/library/windows/desktop/ms738596%28v=vs.85%29.aspx


Записан

while (8==8)
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #49 : 11-06-2013 09:24 » 

Согласен со Sla: кто вообще решил, что по условию задачи непременно надо, чтобы по сети на всех уровнях путешествовали пакеты (на уровне IP) и фреймы (на уровне Ethernet), вмешающие в себе непременно все 600 байт? Это создавать себе проблему на ровном месте.

Имеет значение только поток пользовательских байтов. То, что он делится на блоки по 600 байт, это сетевые протоколы не волнует. Игры со всякими MTU и прочим - это лишь мероприятия по оптимизации потока, чтобы фрагментация была меньше, и нагрузка на хосты и маршрутизаторы была ниже, а также была бы меньше задержка.

Главный вопрос: какая пропускная способность канала в пользовательских байтах/сек нужна, и какая задержка в прохождении информации допустима? Ни автор темы, ни кто другой почему-то этих вопросов не ставит, хотя они - основа для выбора сетевого транспорта как в части протоколов, так и в аппаратной части.

Кроме того, Wi-Fi - это среда фактически "с общей шиной" (в терминах Ethernet), т.е. помехи в эфире или другие точки на том же канале приводят к резкому снижению скорости. И если в проводных сетях эта проблема решается изоляцией сегментов канального уровня через коммутаторы, то в радиоэфире это невозможно. Поэтому говорить о 54 Мб/с оправдано лишь в идеальных условиях: когда на канале нет других точек и иных помех (от грозы до иной техники). Наконец, и расстояние имеет значение, и качество, и мощность передающих и принимающих устройств.

Таким образом, первым делом надо протестировать сам канал: какова реальная скорость передачи. И только потом уже размышлять о порядке приёма/передачи нужных блоков по 600 байт - поодиночке их обрабатывать или группами накапливать в буферах.

Итак:
- Какова реальная (наблюдаемая на практике) пропускная способность канала? Сомневаюсь, что там 54 Мб/с (802.11g) или 600 Мб/с (802.11n).
- Какова расчётная пропускная способность канала по условию задачи? Каждую мс по 600 байт 600 000 байт/сек чистых + ну скажем 50% для худшего случая служебного трафика самих сетевых протоколов (разных заголовков, пингов, синхронизаций, повторной передачи битых пакетов и т.п.) - итого округлим до примерно 1 Мб/сек или примерно 8 Мбит/с. Что, в общем-то с большим запасом позволяет любой современный транспорт на близкой дистанции.
- Каковы допустимые задержки при передачи (от момента начала отправки до момента конца получения блока в 600 байт)?
« Последнее редактирование: 11-06-2013 09:32 от Dimka » Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #50 : 11-06-2013 09:37 » 

Цитата
Главный вопрос: какая пропускная способность канала в пользовательских байтах/сек нужна, и какая задержка в прохождении информации допустима? Ни автор темы, ни кто другой почему-то этих вопросов не ставит

Я пАпрАшу...
Это было во втором посте.
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
locator
Постоялец

ru
Offline Offline

« Ответ #51 : 11-06-2013 09:38 » 

ну вот такой код на стороне передающего клиента
Код: (C++)
while(1)
    {
          send(my_sock, buf, sizeof(_DEV_DATA), 0);
          Sleep(10);
    }
должен 100 раз в секунду передавать
Записан
darkelf
Молодой специалист

ua
Offline Offline

« Ответ #52 : 11-06-2013 09:42 » 

ну вот такой код на стороне передающего клиента
Код: (C++)
while(1)
    {
          send(my_sock, buf, sizeof(_DEV_DATA), 0);
          Sleep(10);
    }
должен 100 раз в секунду передавать
к сожалению - не должен. Sleep(10) ждёт как минимум 10 миллисекунд, а как максимум - в зависимости от загрузки машины. В некоторых случаях даже при Sleep(10) и отсутствии дополнительных действий, он будет всегда ждать как минимум 15(или 16) миллисекунд, т.к. системный тик в Windows будет именно таким.
Записан
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #53 : 11-06-2013 09:44 » 

darkelf, это не суть важно
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
locator
Постоялец

ru
Offline Offline

« Ответ #54 : 11-06-2013 09:47 » 

а я Sleep(1) ставил, скорость практически не растет
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #55 : 11-06-2013 10:19 » 

locator, во-первых, если у тебя такой цикл, то как ты измеряешь скорость? Где собственно код измерения скорости?

Во-вторых, это код передающей стороны, а как обстоит дело на принимающей? Может у тебя там машина "зашивается" при парсинге или в каких-либо обработках. Разумеется, буферы не резиновые, и передача будет идти не быстрее, чем приём.

В-третьих, ты ничего не сказал по поводу Wi-Fi. Например, с какой скоростью происходит копирование большого файла между соединёнными Wi-Fi машинами? Может там у тебя эфир такой, что и 1 Мб/с - роскошь.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
darkelf
Молодой специалист

ua
Offline Offline

« Ответ #56 : 11-06-2013 10:23 » 

darkelf, это не суть важно
Sla, просто в данном случае рассчитывать на 100 пакетов в секунду как-бы вообще не приходится, даже на гигабитном ethernet-е (т.к. проблема вовсе не в нём), что уже говорить про wi-fi.
Записан
sss
Специалист

ru
Offline Offline

« Ответ #57 : 11-06-2013 10:41 » 

а я Sleep(1) ставил, скорость практически не растет

Так ты счётчик за секунду посчитай и поймешь сколько у тебя вызовов в секунду.. Получается ты блокируешься в send. Переходи к перекрытому вводу выводу..
« Последнее редактирование: 11-06-2013 10:43 от sss » Записан

while (8==8)
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #58 : 11-06-2013 10:43 » 

Ну... тут скорей нужна математика.

50Мбит/с ~ 5Мб/с

делим на 600, получаем 8000 пакетов в сек

зы... я не ошибся в расчетах?
Та какая разница, какого размер тик. Пусть будет какой будет.
Я где-то в расчете ошибся?
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
sss
Специалист

ru
Offline Offline

« Ответ #59 : 11-06-2013 10:48 » 

Я где-то в расчете ошибся?

Специфика WiFi большие задержки перехода в эфир.. При этом используется синхронный вызов отправки с ожиданием результата.
Записан

while (8==8)
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #60 : 11-06-2013 10:55 » 

Да сколько можно намекать?

Какая пропускная способность канала?
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
darkelf
Молодой специалист

ua
Offline Offline

« Ответ #61 : 11-06-2013 10:58 » 

Ну... тут скорей нужна математика.

50Мбит/с ~ 5Мб/с

делим на 600, получаем 8000 пакетов в сек

зы... я не ошибся в расчетах?
Та какая разница, какого размер тик. Пусть будет какой будет.
Я где-то в расчете ошибся?
там, кроме 600 байтов пользовательских данных, будет ещё заголовок TCP (минимум 20 байт), заголовок IP (20 майт), к сожалению не знаю, как в wi-fi, но у ethernet будет ещё MAC-загловок (минимум 22 байта) и его контрольная сумма и межфреймовое пространство (16 байт), т.е. на каждые пользовательские 600 байтов будут расходоваться минимум ещё 80 байт. Далее, т.к. это tcp/ip, а не udp, то тут ещё будет квитирование, т.е. передали данные и ждём подтверждение и так практически на каждое сообщение. Обратно будет идти гораздо меньше данных, но т.к. это запрос-ответ - передающей стороне придётся ждать. Да и как говорил Dimka у самого wi-fi может быть много всяких своих заморочек типа помех.
Записан
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #62 : 11-06-2013 11:06 » 

ну так я ж привел приблизительный расчет.
Я всегда уменьшаю, округляю, как говорил мой преподаватель по ТАУ - меня не интересует точность ваших расчетов до 6 знака. У вас погрешность  измерителей 2%.
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
sss
Специалист

ru
Offline Offline

« Ответ #63 : 11-06-2013 11:08 » 

Вообще хотя бы пинг с 600 байтным пакетом
Записан

while (8==8)
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #64 : 11-06-2013 12:03 » 

Ну вот я свой wi-fi маршрутизатор по стандарту n (до 600 Мб/с), находящийся от меня в паре метров, пингую: начиная с пакета 1200 и времени отклика 1 мс дальнейшее увеличение пакета ведёт к такому же линейному возрастанию времени отклика. 2400 - 2 мс, 4800 - 4 мс, 9600 - 7 мс, 19200 - 13 мс и т.д. При этом у меня в эфире висит 15 точек доступа и, очевидно, не меньшее число клиентов.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #65 : 11-06-2013 12:31 » 

Э... не путайте ТС

...........

Как заставить транспорт передать только один пакет получателю?

Предлагаю первейшим делом не пользоваться термином «пакет». Это снимет главную проблему данной темы.

Проблема ТС решается типовым алгоритмом: читать пока не наберется 600 байт.


Добавлено через 4 минуты и 37 секунд:
Итак:
- Какова реальная (наблюдаемая на практике) пропускная способность канала? Сомневаюсь, что там 54 Мб/с (802.11g) или 600 Мб/с (802.11n).
- Какова расчётная пропускная способность канала по условию задачи? Каждую мс по 600 байт 600 000 байт/сек чистых + ну скажем 50% для худшего случая служебного трафика самих сетевых протоколов (разных заголовков, пингов, синхронизаций, повторной передачи битых пакетов и т.п.) - итого округлим до примерно 1 Мб/сек или примерно 8 Мбит/с. Что, в общем-то с большим запасом позволяет любой современный транспорт на близкой дистанции.
- Каковы допустимые задержки при передачи (от момента начала отправки до момента конца получения блока в 600 байт)?
Данный вопрос я уже поднимал. И т.к. некогда детально изучал протокол (на тот момент максимум был 54 Мбит/с), то описал предстоящие трудности и сделал свои оценки: https://forum.shelek.ru/index.php/topic,29445.msg289140.html#msg289140

Добавлено через 5 минут и 3 секунды:
Да сколько можно намекать?

Какая пропускная способность канала?

В первом посте сказано, что 50 Мбит/с. Т.к. таковой скорости не значится в стандартах, предполагаю, что речь о 54 Мбит/с.
« Последнее редактирование: 11-06-2013 12:41 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #66 : 11-06-2013 13:00 » 

Цитата: RXL
Проблема ТС решается типовым алгоритмом: читать пока не наберется 600 байт.
Проблема может быть ещё и в обработке. Тогда решение будет: читать в одной нити во внутреннюю очередь, а в в другой нити обрабатывать. Ибо каждый запрос на чтение - это, вообще, обращение процесса к ядру, что в масштабе времени 1 мс может быть критичным. И поэтому может возникнуть потребность делать это пореже, читая/записывая много блоков разом - буферизация ввода-вывода.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #67 : 11-06-2013 13:04 » 

50 и 54 - не важно и я сказал почему. Для оценки пропускной способности канала

50мбит /10  чтоб получить количество байт в секунду.

получили 5мБ/с - не ошибся?

"блок данных" = 600 байт

считаем сколько таких блоков можем пропустить?
8000 блоков в секунду - не ошибся?




Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
darkelf
Молодой специалист

ua
Offline Offline

« Ответ #68 : 11-06-2013 13:24 » 

Если верить http://www.fotonx.ru/index.php/2011-08-17-12-36-50/76--wi-fi.html, то реальная скорость 54Мбит/с и даже 50Мбит/с быть не может, а будет максимум до 24Мбит/с. Ну а дальше, как уже говорилось, накладные расходы, roundtrip-ы в tcp/ip и прочие радости. Возможно 1000 пакетов в секунду можно будет и не набрать.
Записан
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #69 : 11-06-2013 13:40 » 

фух... пост №68 Улыбаюсь
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
locator
Постоялец

ru
Offline Offline

« Ответ #70 : 12-06-2013 14:20 » 

я тут подумал, нельзя ли реально посмотреть объем информации, которую
получает приемник (сервер то есть)? сам я такую прогу вряд ли напишу,
может какие стандартные проги есть? желательно, что бы была возможность
как в терминале-  каждый байт записать в файл, а потом поглядеть, что же в файле.
Записан
darkelf
Молодой специалист

ua
Offline Offline

« Ответ #71 : 12-06-2013 14:30 » 

locator, wireshark/windump. Winpcap, через которую работают данные программы что-то там вроде умела, правда судя по FAQ (http://www.winpcap.org/misc/faq.htm#Q-16) - работает это не всегда.
« Последнее редактирование: 12-06-2013 14:36 от darkelf » Записан
sss
Специалист

ru
Offline Offline

« Ответ #72 : 13-06-2013 01:53 » 

Правильно - записать каждый байт, не IP пакет... А то вдруг TCP и всё, хана, пропал дом..
« Последнее редактирование: 13-06-2013 01:58 от sss » Записан

while (8==8)
sss
Специалист

ru
Offline Offline

« Ответ #73 : 13-06-2013 02:01 » 

locator, не помогут всякие wincap. В лучшем случае увидите лог разбитый на "блоки данных" IP, которые надо будет ещё сшивать в поток. Там будут и повторы передач, и регулирование окон и бог его знает что ещё.  
Записан

while (8==8)
locator
Постоялец

ru
Offline Offline

« Ответ #74 : 13-06-2013 05:15 » 

darkelf, программа отличная, все что льется в сеть - видно! к тому же еще исходниками.
видно, что мои данные режутся на пакеты размером 1460 байт и 616 байт.
никаких повторов и пропусков не наблюдается. передача идет сильно неравномерно:
много промежуточных пакетов по 70 байт натыкано, и еще какие-то загадочные
пакеты нулевой длины с локального ноута. Я полагаю равномерным такой сбор
данных никогда не сделать.
В передающем потоке поставил Sleep(0), получил обновление данных 815 раз/с.
Большего от данного соединения наверное не получить, но этот результат меня очень
устраивает!
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #75 : 13-06-2013 06:56 » 

50 и 54 - не важно и я сказал почему. Для оценки пропускной способности канала

50мбит /10  чтоб получить количество байт в секунду.

получили 5мБ/с - не ошибся?

"блок данных" = 600 байт

считаем сколько таких блоков можем пропустить?
8000 блоков в секунду - не ошибся?

Слав, ты ошибся.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
darkelf
Молодой специалист

ua
Offline Offline

« Ответ #76 : 13-06-2013 07:31 » 

darkelf, программа отличная, все что льется в сеть - видно! к тому же еще исходниками.
В передающем потоке поставил Sleep(0), получил обновление данных 815 раз/с.
Большего от данного соединения наверное не получить, но этот результат меня очень
устраивает!
Как вариант - если потери данных не критичны - попробуйте перейти на UDP - будет шанс получить больший поток за счёт отсутствия ожидания подтверждения, но если приёмник будет не успевать обрабатывать данные, или будут какие помехи - данные будут теряться.
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #77 : 13-06-2013 07:57 » 

darkelf, на Wi-Fi UDP - это всегда стрёмно, поскольку не управляешь факторами внешних влияний на сеть. Это по проводу, особенно экранированному, можно более-менее с большой вероятностью быть уверенным.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
locator
Постоялец

ru
Offline Offline

« Ответ #78 : 13-06-2013 08:29 » 

обязательно попробую, для целостности данных можно ведь считать crc.
если будет много ошибок, ну значит не судьба.
Записан
darkelf
Молодой специалист

ua
Offline Offline

« Ответ #79 : 13-06-2013 08:32 » 

locator, сами данные портится не будут, точнее если будут, то Вы об этом не узнаете - там сам стек считает контрольные суммы, и если что-то не сошлось, то сообщения отбрасываются. Узнать о том, что пакеты побились можно только по их отсутствию.
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #80 : 13-06-2013 08:43 » 

darkelf, на Wi-Fi UDP - это всегда стрёмно, поскольку не управляешь факторами внешних влияний на сеть. Это по проводу, особенно экранированному, можно более-менее с большой вероятностью быть уверенным.

Приходилось лет 10 назад писать логер для UDP-протокола. Т.к. данные после предобработки загружались в БД, то опасался возможной потери. По этому реализовал следующую архитектуру: приложение многопоточное (приемник, диспетчер, обработчик, две очереди — приема и обработки) прием осуществляется в очередь. Если очередь обработки заполнена ниже порога, диспетчер перебрасывает данные из очереди приема в очередь обработки. Если очередь обработки заполнена, а очередь приема выросла больше порога, создается временный файл в спец.директории и туда сбрасываются данные из приемной очереди, когда очередь на обработку опустеет, сперва подкачаются данные из временных файлов (также при запуске приложения). Система очередей позволяла оперативно принимать большой поток, система с файлами позволяла сглаживать блокировки БД (например при постобработке данных). Для теста искусственно создавал блокировку БД и в буферах в памяти и в файлах накапливалось до сотен МБ и после снятия блокировки все обработалось без потерь. Если памяти достаточно много и гарантия доставки не нужна, то можно обойтись без файлов — только очередь заданий в памяти.

Что-то я неправильно сперва понял процитированое: «на Wi-Fi UDP». Поддерживаю: WiFi дает низкую надежность и для гарантии доставки нужны подтверждения, что съедает плюсы над TCP.
« Последнее редактирование: 13-06-2013 08:47 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
sss
Специалист

ru
Offline Offline

« Ответ #81 : 13-06-2013 08:50 » 

Надо просто перейти от синхронного вызова send к асинхронному и при этом остаться в TCP..
TCP пошлёт все как надо - сериями. Подтверждения будут на всю серию.

И про очереди RXL правильно сказал - по другому асинхронно никак.

Хотя вроде уже всё устраивает?
« Последнее редактирование: 13-06-2013 08:53 от sss » Записан

while (8==8)
locator
Постоялец

ru
Offline Offline

« Ответ #82 : 14-06-2013 03:42 » 

В плане обмена все пока работает.  Еще один момент: если мне надо
знать интервал времени между последовательными приемами (всей
структуры данных), то лучше наверное включить время в состав этой
структуры? На приемном сервере время смысла нет измерять.
Записан
sss
Специалист

ru
Offline Offline

« Ответ #83 : 14-06-2013 03:51 » 

знать интервал времени между последовательными приемами

Где его ещё можно измерить как не на приёмной стороне?
Записан

while (8==8)
locator
Постоялец

ru
Offline Offline

« Ответ #84 : 14-06-2013 05:35 » 

можно там где данные сформировались пред передачей, засечь момент времени и запомнить его.
на приемной стороне все склеивается из разрезанных частей, где тут время считать?
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #85 : 14-06-2013 06:46 » 

Я бы фиксировал время и размер на стороне источника. Лучше данные структуировать, чем ориентироваться на фиксированные блоки. Гибче будет.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #86 : 14-06-2013 06:50 » 

в твой  блок данных подключай время.
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #87 : 14-06-2013 07:17 » 

Так может и подобие real time не нужно будет, раз время в логах записано.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
locator
Постоялец

ru
Offline Offline

« Ответ #88 : 17-06-2013 04:13 » 

воткнул время в структуру данных, все нормально считается: t = GetTickCount().
ну понятно, с точностью времени расчета самих данных. а если у считающего
данные потока повысить приоритет, время точнее будет определяться?
Записан
darkelf
Молодой специалист

ua
Offline Offline

« Ответ #89 : 17-06-2013 05:11 » 

воткнул время в структуру данных, все нормально считается: t = GetTickCount().
ну понятно, с точностью времени расчета самих данных. а если у считающего
данные потока повысить приоритет, время точнее будет определяться?
повысить точность можно через API мультимедиа-таймеров, см. timeBeginPeriod()
Записан
Страниц: 1 2 3 [Все]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines