- TCP/IP в режиме реального времени, vic, 18:09 , 22-Июл-07 (1)
- TCP/IP в режиме реального времени, int _0dh, 12:31 , 23-Июл-07 (2)
- TCP/IP в режиме реального времени, perece, 18:31 , 23-Июл-07 (3)
- TCP/IP в режиме реального времени, Gor, 19:27 , 25-Июл-07 (4)
>> часть кода можно увидеть в темах, которые я открывал раньше(хотя там и изменилось многое). > >ссылочку давай. поиск че-то ниф не рулит.. > >там в сокет не через fdopen/sprintf пишется случайно??? > >\^P^/ Клиент: for(i=10000;i<=20000;i++) { gettimeofday((struct timeval *) &tv, 0 ); actual_time = localtime( &(tv.tv_sec ) ); strftime(vorbuffer,9, "%H:%M:%S", localtime( &(tv.tv_sec ) ) ); length=sprintf(buffer,"%ld\t%s.%06ld\n\r",i,vorbuffer, tv.tv_usec); send(sock_fd, buffer, length, 0); } Сервер: char puffer_our_time[9]; length = recv(client_fd, puffer_find_number_time,23, 0); puffer_find_number_time[length]='\0'; gettimeofday( &tv, 0 ); actual_time = localtime( &(tv.tv_sec ) ); strftime( puffer_our_time, 9, "%H:%M:%S", localtime( &(tv.tv_sec ) ) ); if (length != 0) { printf("%s.%ld\t\t%s",puffer_our_time,tv.tv_usec,puffer_find_number_time); } else { printf("Connection closed by remote host.\n"); break; }
- TCP/IP в режиме реального времени, Gor, 19:32 , 25-Июл-07 (5)
Насчёт ошибки в коде, - вполне возможно, опыта у меня толком в программировании практически нету.Что касается UDP,- попробовал сегодня, однако теряются некоторые сообщения, как и положено, насколько я понимаю в udp. Но зато скорость на много порядков выше и никаких проблем с пересылкой нескольких пакетов за один раз... Что меня удивляет с udp,- когда контролирую пересылку с помощью Wireshark, вижу, что все пакеты были отосланы и находились в проводе. Но в сохранённом файле некоторых сообщений не хватает. В конце персылки совсем выпадают последние 20-30 сообщений. Если я правильно понимаю,- это означает, что проблемы возникают н апринимаюъей стороне. Маленкий буфер? Или что могло бы это быть ещё. Для информации,- связь происходит в маленькой сетке с одним хабом, двумя машинами(с embedded Linux,PowerPC) и контролирующим работу Ноутбуком, где и работатет Wireshark.
- TCP/IP в режиме реального времени, tester, 01:49 , 27-Июл-07 (6)
- TCP/IP в режиме реального времени, Gor, 09:53 , 27-Июл-07 (7)
>В юдипи нет такого понятия как размер окна. Поэтому там все пакеты >пуляються в сеть сразу. Соответственно: буфера не хватило - пакеты потерялись... Я тоже уже об этом подумал,- сегодня хотел как раз посмотреть, как буффер в УДП увеличить можно. >Может кстати в TCP проблемы из-за размера окна. Мож подтверждения задерживаются... Окно достаточно большое на обоих машинах декларируется,-посмотрю повнимательнее, что с ним может быть, спасибо. Подтверждения задерживаются,- это как раз то, что и происходит. Через практически одинаковое время каждый раз. Как я понимаю, на одной машине сообщения попадают в буффер перед отсылкой, затем, когда приходит подтверждение от другой на предыдущие пакеты,- она отсылает со следующим интерраптом все находящиеся в нём пакеты за один раз. Возможно может помочь, если я время срабатывания интеррапта (каким-то образом? ) на обоих машинах уменьшу? >Может в каждом пакете устанавливать флаг PUSH? Он устанавливается автоматически у меня, практически всегда,- почему иногда нет,- не знаю...
- TCP/IP в режиме реального времени, vic, 17:45 , 27-Июл-07 (8)
- TCP/IP в режиме реального времени, Gor, 23:35 , 27-Июл-07 (9)
>Все верно, пакеты могут теряться, скорость выше (отсутствие ожидания подтверждения). >Обработка потери пакетов в этом случае на стороне приложения. > >Как я понял передача идет на максимуме возможностей? Да, я пробовал на максимуме,- в этом случае в TCP/IP пересылаются практически всегда множество пакетов за один раз.Возможное решение,- встроенная пауза в 5мс, тогда всё работает чётко, но не так быстро. В UDP/IP теряются до 25% сообщений на максимуме. При паузе в 0,5мс,- все пакеты доходят без потерь. При этом я также попробовал CAN-бус,- он при задержке в 0,5 мс оказывается быстрее тисипи и удп с такими же задержками, при том что работает на 250Кбит/с!!! >Хаб штука железная однако одно дело ваш ноут который тупо только слушает >что в проводах, другое дело приемная сторона которая может и посылать >пакеты в тоже время, т.е. если не фул-дуплекс (да и с >ним может), то хаб в ноут может отдавать весь поток, а >в приемную сторону не весь (т.к. коллизии мешают). Это идея!!! Спасибо большое,- обязательно проверю работу программы без "Ваершарка". При УДП вижу в нём при этом исключительно удп сообщения от одного к другому, то биш параллельно ничего не происходит. В ТСП конечно тратиться время на подтверждение, но так как отсылающая сторона ничего не посылает, пока не получит ответа,- коллизий должно бы не происходить. Единственное слабое место,- "Ваершарк". Интересно, как он работает? Принимает поток и направлаяет его дальше? >Дальше, сетевая карта >может работать на приемной стороне чуть медленнее чем положено, например что-то >фигово с сопряжением с системной платой (наука о контактах) как результат >потери на приемной стороне. Сетевой карты как таковой нет,- всё происходит в процессоре(MPC 5200B). Проверить скорость,- хм, даже не знаю как,- приходиться полагаться на документацию, а в реализации конечно могут быть глюки... >[оверквотинг удален] > >выш вы приводили кусок кода сервера где: > if (length != 0) > > { > >printf("%s.%ld\t\t%s",puffer_our_time,tv.tv_usec,puffer_find_number_time); > } >Это в файл перенаправлено или на консоль? (консоль имеет свои задержки). >stdout - строчная буфферизация. может быть причиной. Я перенаправляю с консоли в файл( ./server > abc.txt), - чтобы не тратилось время на вывод сообщений и отправку их на консоль, которая находится на ноуте(у машин нет ни экранов, ни клавиатуры)-дополнительное время и коллизионы. Кроме того могу затем внимательно весь файл изучить. Пробовал раньше и с (fprintf),- там примерно те же проблемы. >Как выше писал может причина с fsync. Можно попробовать проверить так - >создать мега-буфер (так чтобы туда минут 5 лога поместилось) в памяти >и писать не в файл (fprintf), а в этот буфер (sprintf), >когда буфер забьется сбросить его в файл и потом проанализировать, а >были ли задержки в таком случае. Посмотрел сейчас ман к fsync,- получается с его помощью я могу писать пакеты без буфферизации в printf i fprintf(хотя есть ли она в fprintf не знаю точно) сразу в память, так? Я пока не понял, как мне это сделать, надо будет в понедельник посмотреть на работе повнимательнее. Также попробую с мега-буфером,- спасибо большое за идею! >По поводу PUSH - есть опция включающая этот режим (setsockopt(TCP_NODELAY) - отключить >алгоритм Нэгла), без нее флаг не ставиться если не системная настройка >(может быть какой-то тюнинг сделан в той же embedded linux?). PUSH в тсп у меня обычно включён по умолчанию. Видимо тюнинг. Хотя я пробовал "выключать" режим Нэгла, - тогда пакеты отсылались сразу по мере поступления, но после десятого(в среднем) отсылка приостанавливалась и шло ожидание ответа или возможно просто ответ поспевал к этому времени. В момент приёма и обработки подтверждения скапливалась очередная порция пакетов,- которые и отсылались "кучкой" в следующем сообщении(обозначил так евернет-пакет, так как пакет под свой стринг определил ранее). >пользователь обычный или рут? это к вопросу приоритета, а мало ли... :) >это я уже фантазирую. на машинах рут, других работающих приложений нет.
- TCP/IP в режиме реального времени, anonymous, 03:36 , 28-Июл-07 (10)
- TCP/IP в режиме реального времени, Gor, 23:26 , 29-Авг-07 (11)
>Нет, не то. Может быть проблема в том, что fsync запускается >для сброса буферов на диск раз в сколько-то-там миллисекунд, и это >тормозит отпрвку пакетов вашей программой. Предложение было создать мега-буфер, для >того, чтобы не дёргать диск, и соответственно, fsync. Здравствуйте, загрузили на работе другими делами и не было времени на это. А теперь надо в спешке опять этим заниматься,- как всегда:-) Как вы посоветовали,я попробовал создать мега-буффер в оперативной памяти. Сделал это с помощью маллока, который затем расширяется с реаллоком дальше по мере поступления новых строк. После окончания цикла, переписываю всю область в файл с помощью fprintf. Я правильно выделял для этого память или есть другие более лучшие методы? Имеет ли fprintf ограничение по обьёму памяти, которую с помощью него можно переписать в файл? До тех пор, пока речь шла о маленьких обьёмах в размере нескольких килобайт, всё было ок. Когда увеличивается количество пересылаемых сообщений(а оно должно быть порядко миллиона в итоге, - размер до десятков мегабайт (размер оперативки позволяет,- постоянно около 100 МБ свободны)),- получатель недополучает сообщения и так как я ещё не встроил никакой системы выхода из цикла for(), программа просто ждёт поступления новых сообщений. Как встроить этот выход пока не решил, - может быть что-то подскажете? В книге Стивенса нашёл способ с включением таймаута(SIGALARM) (если некоторое время не приходят сообщения по удп, то программа прерывается). Но что за библиотеки необходимо там использовать, я ещё не нашёл. Далее наблюдаю такую картину: когда у отправителя вывожу на экран, что посылаю, сообщения пересылаются гораздо чётче(меньше пропавших).Как только выключаю printf, сразу куча строк теряется. Посредством вывода на экран может быть буффер, который я резервирую, освобождается- поэтому? Спасибо большое всем,кто может мне помочь с этой программой. К сожалению рядом у меня нет никого, кто мог бы мне с ней помочь или все заняты своими делами безвылазно.
- TCP/IP в режиме реального времени, anonymous, 03:26 , 30-Авг-07 (12)
- TCP/IP в режиме реального времени, Gor, 09:18 , 30-Авг-07 (13)
>Память лучше выделить сразу большой кусок, так как при realloc() данные могут >быть перемещены в памяти, а знаит, процессор будет занят тупым копированием >данных. fprintf() лучше заменить на системные вызовы open(), read(), close(), >потому что мало ли какие буферы он сам выделяет и сколько >на это времени тратит. Спасибо болшое за советы,- сейчас попробую. >>и так как я ещё не встроил никакой системы выхода из >>цикла for(), программа просто ждёт поступления новых сообщений. >>Как встроить этот выход пока не решил, - может быть что-то подскажете? > >Зависит от того, какое условие выхода. Условие выхода,- если отправитель заканчивает свой цикл раньше получателя и выходит из программы, получатель должен выйти из цикла for(). Количество шагов и у получателя и у отправителя я одинаковое установил. Соответственно, если некоторые сообщения пропали,- получатель зависает в цикле. Если я при этом данные пишу в мега-буффер, то они теряются, потому как переписывание в файл вставил только по окончании цикла for(). Приходится с Ctrl+C прерывать программу... Поэтому хотел встроить выход из цикла с помощью таймера,который ждёт перед recvfrom допустим 5 секунд, а затем выводит из цикла.Так как сообщения приходят циклично, нормальная пауза составлять должна микро или миллисекунды. Но, как уже писал пока не разобрался с имплементацией этого решения. Может быть посоветуете что-то более простое. >Посредством вывода на экран вы занимаете процессор отправителя "лишней" работой между отправкой >пакетов, поэтому, возможно, количество отправленных пакетов/сек будет меньше, чем раньше, а >значит меньше будет и потерянных. Перепроверю сейчас с паузами вместо printf.
- TCP/IP в режиме реального времени, vic, 09:50 , 30-Авг-07 (14)
- TCP/IP в режиме реального времени, Gor, 11:23 , 30-Авг-07 (15)
>Есть такая мысль, берем программу типа сниффер, ставим на сбор входящего потока. > >Собрав часть потока, достаточную для анализа смотрим лог сниффера на предмет наличия >потерь. >Если сниффер ничего не потеряет, значит дело в программе принимающей пакеты. Иначе >лечить отправителя понижая скорость передачи пакетов. Проверил сниффером Варешарк. Все пакеты отсылаются, - вижу их все в сети. При этом отправитель отсылал без пауз. Значит проблема в принимающей стороне. Попробовал увеличить буффер на приёме до 240 КБ(setsockopt(sock_fd, SOL_SOCKET, SO_RCVBUF, &n(ravnyi 240*1024),sizeof(n)) Не помогло. Значит видимо проблема при переписывании в файл. Попробую сейчас переделать программу, как вы посоветовали. что касается кода,- сейчас он выглядит иначе, так как связь идёт по удп.Привожу актуальный код и перепроверю,что я в нём не учёл с учётом Ваших советов. Server: for(i=10000; i<=99999; i++) { char puffer_our_time[9]; len=sizeof(client_addr); length = recvfrom(sock_fd, puffer_find_number_time,22, 0, (struct sockaddr *) &client_addr,(socklen_t *) &len); puffer_find_number_time[length]='\0'; gettimeofday( &tv, 0 ); actual_time = localtime( &(tv.tv_sec ) ); strftime( puffer_our_time, 9, "%H:%M:%S", localtime( &(tv.tv_sec ) ) ); if (length != 0) { printf("%d\t%s.%ld\t\t%s",i,puffer_our_time,i,puffer_our_time,tv.tv_usec,puffer_find_number_time); } else { printf("Connection closed by remote host.\n"); break; } } Client: for(i=10000;i<=99999;i++) { gettimeofday((struct timeval *) &tv, 0 ); actual_time = localtime( &(tv.tv_sec ) ); strftime(vorbuffer,9, "%H:%M:%S", localtime( &(tv.tv_sec ) ) ); length=sprintf(buffer,"%d\t%s.ld\n",i,vorbuffer, tv.tv_usec); /* printf("%d\t%s\n",i,buffer);*/ err = sendto(sock_fd, buffer, length, 0, (struct sockaddr *) &server_addr,sizeof(server_addr)); if(err==-1) err_exit("send: send() failed"); /* usleep(500);*/ }
- TCP/IP в режиме реального времени, vic, 13:18 , 30-Авг-07 (16)
- TCP/IP в режиме реального времени, Gor, 14:58 , 30-Авг-07 (17)
>> for(i=10000; i<=99999; i++) > >начальное значение сбивает с толку :) Я это сделал, чтобы величина буффера не изменялась. Таким образом на счётчик у меня всегда уходит 5 байт(с 10000-99000), иначе пришлосъ бы подстраиватъся с обоих сторон под увеличивающийся размер пересылаемой строчки. Красота выдачи значений в данный момент роли не играет.Понадобиться более длительное время работы программы,- изменю десqтки тысяч на сотни или миллионы, а заодно и размер буффера. >Я же просил 400 капель, а тут 402 <c> :( >проверку сразу после функции делать, и проверять на < 0 надо. И >анализировать еще значения errno. >man recv Каюсь, Вы совершенно правы. Сейчас всё переделаю и добавлю проверку на -1. Постараюсь не допускать таких глупых ошибок в будущем...
|