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

      вот код:
      ExpandedWrap disabled
            util::CS_LOCK( cs );
         
            struct addrinfo *result = NULL, *ptr = NULL, hints;
         
            ZeroMemory( &hints, sizeof(hints) );
            hints.ai_family     = AF_UNSPEC;
            hints.ai_socktype   = SOCK_STREAM;
            hints.ai_protocol   = IPPROTO_TCP;
            
            int res = getaddrinfo( "192.168.0.77", "443", &hints, &result);
            if (res != 0)
                return S_FALSE;
         
            ptr = result;
         
            res = connect( mConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen );
            if ( res == SOCKET_ERROR)
            {
                closesocket(mConnectSocket);
                mConnectSocket = INVALID_SOCKET;
            }
         
            freeaddrinfo(result);
         
            if (mConnectSocket == INVALID_SOCKET)
                return S_FALSE;
         
            return S_OK;


      если же я создам сам сокет перед connect то все ок. проходит.
      есть подозрение что сокет был создан с левыми параметрами.
      к сожалению в dll он приходит не по ссылке и пересоздать я не могу.
      можно ли как то перед вызовом connect поменять параметры готового сокета: family, socktype, protocol ?
        может быть что просто неправильно передалось значение. Проверить бы значение mConnectSocket до передачи в ДЛЛ и после! Параметры менять не желательно! Скажем если сокет клиент TCP, то прежде чем менять его на UDP, нужно отконнектиться от сервера. Если сокет серверный и мы меняем его на UDP - нам нада поотрубать клиентов.
        Существуют способы shutdown() close() и т.п. - сначала закрываем mConnectSocket, потом - по новой mConnectSocket = socket .. блаблабла!
        шашкой рубить по параметрам в процессе - будет скорей неправильно архитектурно.. Тем более, в такой неустойчивой штуке как винсок.
        Сообщение отредактировано: nemez -
          nemez
          да все проще и сложнее

          созвонился с теми кто другой модуль писал - они под IPv6 семейство сокет создавали.
          поэтому у меня коннект и ругается когда я адрес сервера генерю.

          можно как то у уже созданного сокета но не законнекченного сменить семейство тип и протокол ?
          сокет дестроить нельзя
            Разве что поиграться с setsockopt и этими значениями (они не из сей вроде, но один хрен =) )
              Хрен
              честно говоря так и не вкурил как созданному сокету сменить семейство AF_INET6 на AF_INET
                progman
                чесно говоря подобного плана задачи стоят и у меня самого, но все руки не доходят и откладываю на потом.
                Там весь прикол в том что структура sockaddr_in или там sockaddr для этих протоколов отличается!!!!
                для 6 нада использовать кажись это:
                http://msdn.microsoft.com/en-us/library/ms740504(v=vs.85).aspx
                в мсдн пишут по этому поводу, с примерами кода
                http://msdn.microsoft.com/en-us/library/ms738649(v=vs.85).aspx
                ну и я бы рекомендовал переходить на дот нет фреймворк, там возни меньше и толку больше, при реализации как блокирующих, так и неблокирующих сокетов, интерфейс интуитивно понятный и простой как трехлинейка.
                  nemez
                  ты не понял... система плагинов.
                  чуваки в ядре создают сокет сами ( зачем второй вопрос ) и влепили там семейство AF_INET6
                  грузится моя длл, которая обеспечивает работу с моим сервером.
                  ее задача законнектить их сокет с моим серваком.

                  он, сервак, пока только по IPv4 работает. с IPv6 никогда дел не имел и все попытки законнектить терпят фиаско.
                  код сервера переписывать анрил потому что он уже работает и трогать категорически нельзя.

                  пока тренируюсь на локальном. у локального адрес 192.168.0.7 - пытался скормить его в структуру адресинфо - фиг

                  вот и задумал - а не сменить ли мне у сокета который фактически моя собственность уже семейство протокола с AF_INET6 на AF_INET
                  если бы сокет по указателю передавали бы - я бы не парился прибил старый и создал бы новый а так... мучаюсь

                  ЗЫ за ссылки спасибо изучаю.
                    Цитата
                    вот и задумал - а не сменить ли мне у сокета который фактически моя собственность уже семейство протокола с AF_INET6 на AF_INET

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

                    Цитата
                    если бы сокет по указателю передавали бы

                    а в системе по барабану, как он передан - по ссылке, указателю или вообще через гланды - сокет имеет идентификатор - 1, 2, 3, 5, 10 .....
                    по этому идентификатору система и идентифицирует некоторую структуру где-то в системной памяти. Короче, можно смело убивать и делать реассигн. Можно делать, главное - не внести сумятицу в верхнеуровневые событийные механизмы!

                    Добавлено
                    короче гляди
                    ExpandedWrap disabled
                      x=socket( ....///блаблабла
                      // .....
                      printf("%d\n",x);

                    ну и пусть после создания сокета оно вывело число 10, к примеру!
                    в плагине мы берем и делаем
                    ExpandedWrap disabled
                      int i = 10;

                    скармливаем коннекту в качестве значения SOCKET для коннекта, и вуаля!
                    тоесть то что ты боишься делать - можно, безо всяких указателей и ссылок. Сокет он сам по себе некоторый виртуальный указатель
                      nemez
                      беда в том что вне плагина который пишу я есть еще их работа с сокетом. они его создали. у них есть переменная m_socket которая имеет какое то значение, пусть будет 10
                      я такой вот умный взял и создал новый сокет и законнектил к своему серверу.
                      как я им туда наверх скажу что m_socket уже не 10 а 11


                      Цитата nemez @
                      если некоторые события от этого сокета отрабатываются уровнем выше, то сменив семейство на верхней ступеньке может наступить беда.

                      беда не беда. заодно бы и узнал. только вот как сменить не разрушая сокет??!!
                        попробуй не close() a shutdown() c повторным открытием...
                          Цитата nemez @
                          попробуй не close() a shutdown() c повторным открытием...

                          один фиг не гарантии что при вызове функции socket новый будет иметь такой же дескриптор что и убиенный.
                            самая ближайшее - поднять локально В6 сервак, и коннектиться на него! Ибо затея обернется таким гемором, что мало не покажется.
                            Либо в полном объеме согласовать уровни приложения и плагина
                              Кстати, если таки есть связь с разрабами, то мож они могут и персонально для тебя создавать ipv4 сокет? Поменять-то пару строк всего нужно...
                              Судя по документации linux сокетов (которые такие же как и в винде, фактически), даже тип сокета изменять нельзя - можно только читать =(
                                Цитата progman @
                                ситуация такая мне в длл приходит вызов - законнектить сокет на сервер. сокет уже создан до моего вызова, параметры его создания не известны.

                                1. Мне в дллку - это ваша собственная дллка?
                                2. Вызов - это просто заказ на коннект?
                                3. Дллка выступает в роли клиента?
                                4. Причем тут сервер?
                                Сервер создает свой сокет только при поступлении заявки......
                                Что-то я тут логики не нахожу.....
                                Потому что даже IPv6 адреса должны быть приведены к структуре sockaddr.
                                Еще раз и поконкретнее - типа пошагового алгоритма......
                                  Цитата Oleg2004 @
                                  1. Мне в дллку - это ваша собственная дллка?

                                  да. длл моя а ехе не мой. длл это плагинн. сокет создается в ехе и передается в длл.

                                  Цитата Oleg2004 @
                                  2. Вызов - это просто заказ на коннект?

                                  да, просто передача сокета в длл чтобы длл сама решила к какому серверу его, сокет, коннектить


                                  Цитата Oleg2004 @
                                  3. Дллка выступает в роли клиента?

                                  как часть клиента. длл просто должна определить к какому серверу коннектиться также она выполняет роль "перекодировщика" . т.е отсылаемые пакеты приводит к стандарту понятному серверу под который она писалась.


                                  Цитата Oleg2004 @
                                  4. Причем тут сервер?

                                  именно тут вообще не причем. он где то там далеко стоит и ждет когда к нему постучатся поговорить ;-)


                                  Цитата Oleg2004 @
                                  Еще раз и поконкретнее - типа пошагового алгоритма......

                                  есть ехе. он через систему плагинов ( длл ) может работать с различными серверами. каждый сервер имет свой собственный протокол, порт ип.
                                  1.внутри ехе создается сокет.
                                  2. после создания сокета он как параметр передается в длл ( происходит вызов функции doConnect )
                                  3. внутри длл вызывается connect
                                  4. возвращается OK или FAILED

                                  с AF_INET6 работать не умею а в ехе сокет создается именно как AF_INET6. Попробовал поработать с IPv6 - куча непонятных проблем. Скажу честно ковыряться и разрешать их особого желания нет. Хочется по простому.
                                  вызов getaddrinfo для IPv4 адреса и последующий вызов connect и ведет к ошибке 10014.

                                  чтобы облегчить себе жизнь вижу два варианта:
                                  1. удалить старый сокет, создать новый и надеяться что дескриптор нового сокета будет равен старому иначе беда.
                                  2. изменить параметры полученного сокета так если бьы он слздавался как AF_INET

                                  п.1 я сделал - вроде ниразу не нарвался чтобы дискриптор менялся. но гарантии нету.
                                  как сделать п.2 потому что в моем случае он более правильный из всех неправильны я не знаю. ничего по теме не нагуглил.
                                  1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                                  0 пользователей:


                                  Рейтинг@Mail.ru
                                  [ Script execution time: 0,0573 ]   [ 15 queries used ]   [ Generated: 22.11.25, 10:26 GMT ]