На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Страницы: (2) [1] 2  все  ( Перейти к последнему сообщению )  
    > UDP клиент и сервер , Как?
      Хочу сделать следующее:
      Клиент на Винмобаил каждые 20мС(желательно) шлет на сервер несколько байт.
      Сервер шлет ему свои несколько байт, затем подготавливает данные для следующего раза.
      Клиент будет только один.

      Для опытов я сделал оконные клиент и сервер на ВинХР на "большом" компе, пока без таймера.
      Попытка реализовать это увенчалась частичным успехом , все работает,но только один раз :), после чего(при следующей попытке), клиент зависает. :'(
      Если если перезапустить сервер, то клиент может послать еще одно сообщение.
      Пробовал консольный сервер из "Самоучителя по игре.." ,c ним все работает, ну так он сам все время "висит" в while(1).
      Думаю, я что-то в принципе не так делаю , поэтому код приводить смысла нет.Может, кто подскажет как надо.
      Пишу на Си.
      Сообщение отредактировано: Alexei -
        Ну, сервер UDP обязан висеть на recvfrom()- иначе это не сервер, а одноразовый шприц. :)
          Цитата Oleg2004 @
          Ну, сервер UDP обязан висеть на recvfrom()- иначе это не сервер, а одноразовый шприц. :)

          Почему ?
          Лучше висеть на select.
          Сделаем так:
          1. Для UDP нет разницы - "клиент" и "сервер" это будет почти одна и та-же программа.
          Тот, кто начинает обмен, называется клиентом.
          2. Для удобства (отладки) клиент будет слушать один порт, сервер - другой.
          3. С некоторым тайм-аутом ожидаем приёма сообщения. исключительно для того, чтобы
          опросить, например, клавиатуру и корректно завершить приложение.
          4. Если сообщение получено проверим опять же селектом готовность к передаче
          и пошлём ответ.
          5. Проверим условие на окончание работы приложения. Если нет, всё повторим с пункта 3.

          Разница между клиентом и сервером только в том, что клиент первым посылает сообщение,
          а потом ожидает приёма. Послать сообщение можно в том числе и по нажатию какой - либо клавиши
          в пункте 5.
            Цитата Oleg2004 @
            обязан висеть

            Висеть, но не вешать все.

            Цитата ЫукпШ @
            Лучше висеть на select.

            У меня он вообще не используется ! :o
            Ну я еще тот пограмист ;)
            Все решилось вставкой бесконечного цикла в процесс с recvfrom.

            Спасибо.
              Если верить StackOverflow, то вот работающий рецепт на select http://stackoverflow.com/questions/1559208...ith-select-in-c
              Хотя я для UDP тоже гоняю recvfrom в цикле - и пока проблем не ощутил.
                  Цитата ЫукпШ @
                  Лучше висеть на select.

                  Кто бы сомневался... :D
                  К сожалению, я именно это и предполагал, предложив топикстартеру цикл с recvfrom.
                  Цитата Alexei @
                  У меня он вообще не используется ! :o
                  Ну я еще тот пограмист ;)
                  Все решилось вставкой бесконечного цикла в процесс с recvfrom.
                  :)

                  Добавлено
                  Цитата ЫукпШ @
                  1. Для UDP нет разницы - "клиент" и "сервер" это будет почти одна и та-же программа.
                  Тот, кто начинает обмен, называется клиентом.

                  И с этим согласен, да вот только на сервере bind()обязателен, а на клиенте - три варианта - без бинда, с коннектом или биндом...
                    Рад что вас развеселил! :)
                    Вобщем у меня как-то все работает, но я смотрел Wireshark-ом: часто то сервер, то клиент шлют "деформированные" пакеты , так что , наверно, имеет смысл прислушаться к вашим советам по select. Хотя, мне больше понравился EventSelect.
                    Но все примеры даны для консольных программ, а у меня будет оконная(в винмоб , помоему, других нет) .
                    Поэтому никто не будет так любезен показать структурно, как это будет выглядеть в оконной программе?
                      Цитата Alexei @
                      ... я смотрел Wireshark-ом: часто то сервер, то клиент шлют "деформированные" пакеты , так что , наверно, имеет смысл прислушаться к вашим советам по select.

                      Это не совсем понятно. Надо разбираться.
                      Дело в том, что обмен с сервером DNS производится посредством UDP.
                      И если бы дело действительно было так плохо, интернет-сёрфинг
                      был бы не возможным. Или не комфортным.
                      Торрент - клиенты тоже (вроде) используют UDP для передачи информации.
                      Сообщение отредактировано: ЫукпШ -
                        Цитата Alexei @
                        но я смотрел Wireshark-ом: часто то сервер, то клиент шлют "деформированные" пакеты

                        Какой смысл вы вкладываете в понятие "деформированные" пакеты?
                        Насчет Eventselect ()
                        MSDN http://msdn.microsoft.com/en-us/library/aa925696.aspx
                        утверждает, что API для винмобиле не включает WSAEventSelect()или WSAAsyncSelect().
                        Сколько я помню, все варианты для мобильных систем работают на базе спецификации Винсок 1.1
                        А вот select() там есть.
                        Поэтому чисто оконного сетевого приложения найти будет трудно. Придется писать скажем в идеологии консоли, а потом код трансформировать в оконное приложение.

                        Цитата Alexei @
                        как это будет выглядеть в оконной программе?

                        Для начала вы должны познакомиться с идеологией работы оконных приложений.
                        Оконное приложение всегда "висит" в цикле обработки сообщений.
                        Сообщения приходят от системы и передаются по хендлу окна, а обработчик сообщений выполняет необходимые действия. Это так, быстро и на пальцах... :)
                          Цитата Oleg2004 @
                          Придется писать скажем в идеологии консоли, а потом код трансформировать в оконное приложение.
                          А потом этот код вынести в отдельный поток и не думать особо об окнах :)
                            Цитата Adil @
                            этот код вынести в отдельный поток

                            Дык у меня так и сделано в сервере. recvfrom и sendto в потоке.
                            Цитата Oleg2004 @
                            Это так, быстро и на пальцах...

                            На таких пальцах я и сам представляю.:) Непонятно было куда засунуть селект, но если в поток , а из него слать сообщения и в их обработке слать и принимать?
                            Цитата Oleg2004 @
                            утверждает, что API для винмобиле не включает

                            Возможно.
                            Я пишу #include <winsock2.h> и никто не против, :)

                            Цитата Oleg2004 @
                            Какой смысл вы вкладываете в понятие "деформированные" пакеты?

                            Ну "уродливые" , это не я , это Wireshark . Он пишет "malformed" , а в место данных там эррор.А в графе протокол вместо UDP пишет TAPA. (не знаю что это , но догадываюсь первые буквы надо заменить на "ЖО" :) )
                            Причем такие пакеты шлют и тот и другой.
                            Цитата ЫукпШ @
                            Дело в том, что обмен с сервером DNS производится посредством UDP.

                            У меня нет ДНС (я надеюсь :) ) все происходит в локальной сети: смартфон с вай-фаем -клиент , на писи- сервер, меж ними роутер с вай-фай.
                              Цитата Alexei @
                              Непонятно было куда засунуть селект, но если в поток, а из него слать сообщения и в их обработке слать и принимать?

                              Ну, для того чтобы засунуть куда-нибудь селект, надо представлять, что он будет делать.
                              Если у вас UDP-сервер, то на прием он висит на recvfrom(). У него нет внутреннего таймаута, а потому висеть может годами. Если такая ситуация не устраивает, то висят на селекте - но уже с таймаутом. Вот и весь смысл.
                              Цитата Alexei @
                              Я пишу #include <winsock2.h> и никто не против, :)

                              Зря. winsock2.h просто содержит всю информацию winsock.h - и только.
                              Цитата Alexei @
                              Wireshark. Он пишет "malformed", а в место данных там эррор. А в графе протокол вместо UDP пишет TAPA.

                              TAPA (Trapeze Access Point Access Protocol)
                              В Wiresharkе есть клизмы, когда он неправильно определяет протокол и не может его анализировать...
                              А здесь про "malformed"
                              Сообщение отредактировано: Oleg2004 -
                                Цитата Oleg2004 @
                                надо представлять, что он будет делать.

                                Думаю для начала, надо представлять что вообще надо. :)
                                А надо мне изменить работу клиента(работа сервера меня в целом устраивает)
                                Хотелось бы сделать так , чтобы клиент , послав пакет , не зависал, если возникнут проблемы с ответом , а продолжал работу и по таймеру послал следующий пакет.
                                Подозреваю, надо послать пакет sendto-ом , далее подождать в select некоторое время , после чего либо recvfrom, либо ждать сообщения от таймера.
                                sendto , наверно , в обработке сообщения от таймера, recvfrom обработке сообщения от select, а select в потоке. Типа того?
                                  Цитата Alexei @

                                  Думаю для начала, надо представлять что вообще надо. :)

                                  Это ваши проблемы :D

                                  Цитата Alexei @
                                  Подозреваю, надо послать пакет sendto-ом , далее подождать в select некоторое время , после чего либо recvfrom, либо ждать сообщения от таймера.

                                  Не понимаю (увы, я не телепат) зачем нужен таймер, ведь у селекта есть свой таймер таймаута.
                                  Приведу вам простой примерчик для селекта:
                                  ExpandedWrap disabled
                                    #include <sys/time.h>
                                    #include <sys/types.h>
                                    #include <unistd.h>
                                    #define STDIN 0     /* дескриптор файла для стандартного ввода */
                                    main ()
                                          {   struct timeval tv;
                                              fd_set readfds;
                                              tv.tv_sec = 2;
                                              tv.tv_usec = 500000;
                                              FD_ZERO(&readfds);
                                              FD_SET (STDIN, &readfds);
                                                /* Нас не интересуют writefds и errorfds */
                                              select (STDIN+1, &readfds, NULL, NULL, &tv);
                                    /*После нажатия клавиши клавиатуры нажать Enter*/
                                              if (FD_ISSET (STDIN, &readfds))
                                            printf (" Клавиша была нажата! \n ")
                                           else
                                            printf ("Timed out \n ");
                                         }

                                  Селект ждет 2,5 сек, чтобы нажали клавишу на клаве...
                                  Селектом ждать можно чего угодно и как угодно..
                                  0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                  0 пользователей:


                                  Рейтинг@Mail.ru
                                  [ Script execution time: 0,0510 ]   [ 16 queries used ]   [ Generated: 9.05.24, 02:58 GMT ]