На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Страницы: (3) [1] 2 3  все  ( Перейти к последнему сообщению )  
    > sendto , функция возвращает ошибки по непонятным причинам
      Уважаемые форумчане, подскажите пожалуйста кто сталкивался с такой проблемой или хотя бы в каком месте копать.
      Суть проблемы такова. Пытаюсь выдавать ICMP пакеты. Написал класс, использующий функции библиотеки winsock2.h.
      Сам метод класса не стал пока выкладывать. Дело в том, ошибку возвращает функция sendto, в том случае, если
      раскомментировать закоментированные строчки кода. Т.е. если я пытаюсь отдать ей данные, веденные с формы.
      Как это связано я просто не могу понять. Среда C++Builder5. Думал может старый компилятор. Поставил Borland2007,
      перекинул исходники класса, ничего не меняя. Создал такую же форму с Edit и кнопочками, в общем повторил интерфейс
      полностью. И все заработало! Ну я подумал, проблема решена, но сегодня опять столкнулся с ошибкой функции sendto
      и опять по непонятной причине, но теперь уже ошибку вызывает объект Label на форме. Если он обновляется, то функция
      выдает ошибку, если его не трогать, то не выдает. Ошибку выдает 10013 - это в Borland2007 в пятом не помню, возможно такая же.
      Компилировал на другом компе - сначала не выдавал ошибку, потом что то на форме добавил - стал выдавать.
      Короче полная для меня неясность, если кто в курсе просветите!

      ExpandedWrap disabled
        //---------------------------------------------------------------------------
        void __fastcall TForm1::ButtonClick(TObject *Sender)
        {
         tICMP ICMP1;                        
         unsigned char DataOut[512];
         
        // unsigned char d = StrToInt(EditDataOut->Text);
         
         for (int i=0; i<100; i++)
            {
             DataOut[i] = 0x55;
        //     DataOut[i] = d;
            }
         
         AnsiString Res = ICMP1.SendData("192.168.1.1", DataOut, 100);
         if (Res != "OK")
            {
             ShowMessage(Res);
             return;
            }
        }
        //-----------------------------------------------------------------


      Добавлено
      Еще кое что вспомнил! Ошибка вылетает даже если раскоментировать только верхнюю строчку, т.е. где объявляется переменная char и ей присваивается
      значение из объекта Edit. Таким образом связь этих двух событий вообще становится непонятной..
        Columbo
        Цитата
        WSAEACCES
        10013 (0x271D)
        An attempt was made to access a socket in a way forbidden by its access permissions.

        Файрволл, антивирус случайно не блокируют твою программу? Какой-нибудь новый софт недавно устанавливал?
          Цитата Columbo @
          Еще кое что вспомнил! Ошибка вылетает даже если раскоментировать только верхнюю строчку, т.е. где объявляется переменная char и ей присваивается
          значение из объекта Edit.

          Практически сразу возникает вопрос - а что будет, если:
          ExpandedWrap disabled
            //---------------------------------------------------------------------------
            void __fastcall TForm1::ButtonClick(TObject *Sender)
            {
             tICMP ICMP1;                        
             unsigned char DataOut[512];
             
            // unsigned char d = StrToInt(EditDataOut->Text);
             
               unsigned char d = 0x55;
               for (int i=0; i<100; i++) { DataOut[i] = d; }
             
                AnsiString Res = ICMP1.SendData("192.168.1.1", DataOut, 100);
                if (Res != "OK")
                {
                 ShowMessage(Res);
                 return;
                }
            }
            //---------------------------------------------------------------------------

          Сомнительно выглядит возврат функции строкой.
          Достаточно вернуть NO_ERROR (=0), но это дело вкуса.
            Как всегда, форум не программистов, в экстрасенсов. Автор, где тобой написанный класс для ицмп?
            Примеров в сети два вагона, не пойму в чем проблема взять готовое
            http://tangentsoft.net/wskfaq/examples/dllping.html
            ?
              Спасибо за участие, коллеги!
              Итак начну отвечать в режиме LIFO:
              Цитата nemez @
              Автор, где тобой написанный класс для ицмп?
              Примеров в сети два вагона, не пойму в чем проблема взять готовое
              http://tangentsoft.net/wskfaq/examples/dllping.html
              ?

              Дело в том, что я хочу использовать ICMP пакеты для обмена данными, а в библиотеке ICMP.dll функция SendEchoRequest кажется ждет ответа без искажения данных, т.е. что послал - то и принял. А мне надо послал одно - принял что то другое.
              Вот метод класса:
              ExpandedWrap disabled
                AnsiString tICMP::SendData(char* ip_addres, unsigned char* OutBuf, size_t num)
                {
                 sockAddrLocal.sin_addr.S_un.S_addr = inet_addr(ip_addres);
                 sockAddrLocal.sin_family = AF_INET;
                 
                 pIcmpHeader = (struct icmp *) IcmpSendPacket;   // Point at the data area
                 pIcmpHeader->icmp_type = ICMP_ECHO;             // then fill in the data.
                 pIcmpHeader->icmp_code = 0;                     // Use the Sockman instance
                 pIcmpHeader->icmp_id = hInstance;               // handle as a unique ID.
                 pIcmpHeader->icmp_seq = 0;                      // It's important to reset
                 pIcmpHeader->icmp_cksum = 0;                    // the checksum to zero.
                 
                 iPacketSize = ICMP_HEADERSIZE + num;
                 
                 for (size_t i=ICMP_HEADERSIZE, j=0; j<num; i++, j++)
                    {
                     IcmpSendPacket[i] = OutBuf[j];
                    }
                 
                 pIcmpHeader->icmp_cksum = InternetChksum((LPWORD)pIcmpHeader, iPacketSize);
                 
                 if (pIcmpHeader->icmp_cksum !=0 )
                    {
                     iSentBytes = sendto(hSocket, (LPSTR) IcmpSendPacket, iPacketSize,
                     NO_FLAGS, (LPSOCKADDR) &sockAddrLocal, sizeof(sockAddrLocal));
                     if (iSentBytes == SOCKET_ERROR)
                        {
                         int err = WSAGetLastError();
                         return "Error.\r\nThe sendto() function returned a socket error: " + IntToStr(err);
                        }
                 
                     if (iSentBytes != iPacketSize)
                        {
                         return "Error.\r\nWrong number of bytes sent: " + IntToStr(iSentBytes);
                        }
                    }
                 
                 return "OK";
                }


              Повторюсь еще раз, программа работает, если не используется объект Edit, при этом не важно что записывается в массив: константа или переменная.
              Как строка из Edit влияет на функцию sendto - для меня тайна покрытая мраком.
              На другом компиляторе программа заработала и с Edit, но потом начала глючить при использовании объекта Label, причем зависит от того какая
              строка выводится на экран.

              Добавлено
              Цитата ЫукпШ @

              Сомнительно выглядит возврат функции строкой


              Ну просто так удобнее выводить на экран и придумывать коды не надо.
              По поводу Вашего примера реализации - будет работать, Edit же не используется.

              Добавлено
              Цитата Pacific @
              Файрволл, антивирус случайно не блокируют твою программу? Какой-нибудь новый софт недавно устанавливал?

              Нет ничего такого не делал. Опять повторюсь - пакеты высылаются, но при определенных обстоятельствах возникает облом.
                Есть ли уверенность, что размер (массива ?)"IcmpSendPacket"
                действительно не меньше "iPacketSize = ICMP_HEADERSIZE + num" ?
                  Кстати такой вопрос.
                  Вы испытываете свой проект в режиме дебага или делаете автономный экзешник (релиз)?
                    Он значительно больше - 1024 байта. Но будь он меньше, как бы это объясняло данную проблему? В массив кладутся байты, какая разница откуда они берутся?
                      Oleg2004 в режиме дебага
                        Цитата Columbo @
                        Он значительно больше - 1024 байта. Но будь он меньше, как бы это объясняло данную проблему? В массив кладутся байты, какая разница откуда они берутся?

                        Если бы он был меньше, то в этом цикле
                        ExpandedWrap disabled
                           
                          for (size_t i=ICMP_HEADERSIZE, j=0; j<num; i++, j++)  { IcmpSendPacket[i] = OutBuf[j]; }

                        будет выход за границы массива. С любыми последствиями.
                          Цитата Columbo @
                          в режиме дебага

                          Сетевые приложения так не отлаживаются.
                          Режим дебага зачастую - практически во всех средах разработки - достаточно трудно работает со стеком TCP/IP.
                          Это вам не поиск в базе данных отлаживать.
                          Потому я всегда требую от студентов делать релиз. Практика показала глючность режима дебага для сетевых приложений.
                          Сообщение отредактировано: Oleg2004 -
                            ЫукпШ это понятно... но тогда бы выход за пределы был всегда и почти всегда приводил бы к краху программы с соответствующими сообщениями. А тут ошибку возвращает функция, ничего не рушится, а если не использовать компонент Edit, то вообще все ок...

                            Добавлено
                            Oleg2004 Ваше замечание мне кажется наиболее точно объясняет такое поведение. Обязательно проверю это!
                              Цитата Columbo @
                              ничего не рушится, а если не использовать компонент Edit, то вообще все ок...

                              Во во... плавающий глюк вполне может быть именно в дебаге.
                                Цитата Columbo @
                                ЫукпШ это понятно... но тогда бы выход за пределы был всегда и почти всегда приводил бы к краху программы с соответствующими сообщениями.

                                Нет. Это как повезёт.
                                Поведение приложения типа "что-то глючит" как раз хорошо подходит
                                под гипотезу о выходе за пределы массива.
                                  Итак...
                                  На всякий случай увеличил размер массива до 2 кб, а потом до 4 - программа стала просто зависать при отправке.
                                  Сделал релиз - вываливает ту же ошибку.
                                  Переписал exe-шники в одельную папку (до этого запускал просто из билдера): релиз, релиз с библиотеками, дебаг - все программы зависают на передаче.

                                  Раскоментировал закоментированное в следующем коде:
                                  ExpandedWrap disabled
                                    AnsiString tICMP::Startup()
                                    {
                                     WSAStartup(0x0101, &wsaData);
                                     
                                     sockAddrHost.sin_family = AF_INET;
                                     sockAddrHost.sin_port = htons(0);
                                     sockAddrHost.sin_addr.s_addr = 0;
                                     
                                     if ((lpProtocolEntry = getprotobyname("icmp")) == NULL)
                                        {
                                         nProtocol = IPPROTO_ICMP;
                                        }
                                     else
                                        {
                                         nProtocol = lpProtocolEntry->p_proto;
                                        }
                                     
                                     if ((hSocket = socket(PF_INET, SOCK_RAW, nProtocol)) == INVALID_SOCKET)
                                        {
                                         return "Error.\r\nCould not create a RAW socket.";
                                        }
                                     
                                    /*
                                     int err = bind(hSocket, (sockaddr*)&sockAddrHost, sizeof(struct sockaddr_in));
                                     if(err == SOCKET_ERROR)
                                        {
                                         closesocket(hSocket);
                                         return "Error in bind(): " + IntToStr(err);
                                        }
                                     
                                     const char a = 1;
                                     if (setsockopt(hSocket, SOL_SOCKET, SO_BROADCAST, &a, 1) == SOCKET_ERROR)
                                        {
                                         closesocket(hSocket);
                                         return "Error in setsockopt";
                                        }
                                    */
                                     
                                     return "OK";
                                    }


                                  Ошибка перестала вываливаться программа стала передавать, ну и принимать естественно данные веденные с формы.
                                  Другая программа с похожими симптомами тоже перестала вываливать ошибку. Вот только меня терзают сомнения, что
                                  я уже это делал раньше. И почему биндинг сокета при использовании компонента Edit нужен, а без использования не нужен остается для меня загадкой.
                                  Какая разница откуда берутся данные? Причем тут броадкаст тоже не понятно, хотя я где то читал что для RAW сокетов эта опция нужна.
                                  В любом случае как говорится "будем посмотреть!" Завтра проверю на работе.
                                  Сообщение отредактировано: Columbo -
                                  0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                  0 пользователей:
                                  Страницы: (3) [1] 2 3  все


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