Ошибка Winsock 10014 при попытке использовать сокет в Python 3 в Windows

Проблемный участок кода выглядит примерно так:

import socket, my_custom_socket_address_getting_module

underlyingSocketFileno = my_custom_socket_address_getting_module.get()
connectedSocket = socket.socket( fileno=underlyingSocketFileno )
clientAddress = connectedSocket.getpeername()

Где «my_custom_socket_address_getting_module» - это настраиваемое расширение C, которое возвращает адрес открытого сокета на моей машине (как длинный).

Первые две строки работают хорошо, а объект сокета Python выглядит разумным (например, fd и другие свойства сокета выглядят правильно в отладчике), но попытка вызвать getpeername для объекта вызывает следующее исключение:

<class 'OSError'>:[WinError 10014] The system detected an invalid pointer address in attempting to use a pointer argument in a call    

Поскольку я позволяю Python создавать как сокет Python (и, предположительно, так и поддерживающую ОС SOCKET), я понятия не имею, откуда взялся адрес сломанного указателя.

Я вполне уверен, что адрес сокета, передаваемый Python из моего настраиваемого модуля, правильный, и что адрес сокета, который он возвращает, действителен, поскольку расширение отлично работало с моей старой версией Python.

Эта проблема возникла, когда я перешел на гораздо более новую версию Python (3.6.5) - есть ли идеи относительно того, почему эта новая версия будет вести себя так? Предыдущая рабочая версия была Python 1.5.2 (да, действительно).

(ОС - Microsoft Windows 8.1 64, Python 3.6.5, построенная с MSVCC v.1911)

Какая старая версия Python работала? Пожалуйста, добавьте это в ошибку. Чтобы отладить проблему, вы можете попробовать ее со всеми промежуточными версиями Python, и когда вы выясните, какая версия сломала ее, спросите, в частности, в списке рассылки Python, чтобы поговорить с разработчиками.

pts 23.04.2018 10:56

Вы также должны указать, какую версию вы использовали ранее.

Tarun Lalwani 23.04.2018 12:39

@pts Я согласен с тем, что мне придется поступить именно так, если я не найду больше многообещающих потенциальных клиентов. К сожалению, предыдущей рабочей версией был Python 1.5.2, так что здесь есть над чем поработать.

benjamin.hammond 23.04.2018 16:24

Я бы попробовал 2.0.1 (python.org/download/releases/2.0.1), затем 2.7.14 (python.org/downloads/release/python-2714). Если работает только 2.0.1, то можно разделить пополам: попробуйте последнюю версию 2.4 и т. д.

pts 23.04.2018 17:51

Если вам не повезло, что пользователь StackOverflow или пользователь списка рассылки Python не знают ответа, возможно, вам придется проделать утомительную работу, попробовав несколько версий Python.

pts 23.04.2018 17:53

Что означает «возвращает адрес сокета открытого сокета», какой тип C возвращаемого значения?

void 23.04.2018 21:31

Возможно, вы перешли с 32-битного Python (1.5.2) на 64-битный Python (3.6.5)?

mnistic 24.04.2018 01:08

Вы пробовали сбросить winsock? netsh winsock reset в терминале

Jacques Gaudin 24.04.2018 16:05

Какое семейство и тип розетки?

Jacques Gaudin 25.04.2018 01:12

Предполагая, что IPv6 включен в ОС, я бы проверил, был ли Python собран с поддержкой IPv6, проверив socket.has_ipv6. Если нет, то Python отправляет IPv6-адрес в sock_addr, который слишком мал (sock_addr_storage больше и будет подходящим). Python 1.5.2 работает, потому что буфер определен как char addrbuf[256], в котором достаточно места для получения адреса IPv6.

Jacques Gaudin 25.04.2018 11:03
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
3
10
640
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Из Документы Python 3 для конструктора socket.socket:

If fileno is specified, the other arguments are ignored, causing the socket with the specified file descriptor to return.

Возможно, это было очевидно для автора документации, но похоже, что это работает, только если сокет, связанный с передаваемым вами fileno, был создан Python. Если вы пытаетесь подключиться к сокету, который был открыт модулем расширения, Python создаст объект socket с предоставленным вами fileno, но для других свойств сокета (тип, семейство, протокол) будут установлены значения по умолчанию. .

В этом случае сокет был сокетом IPv6, но по умолчанию для сокетов Python используется IPv4. Указание типа и семейства сокета вручную устранило проблему.

«другие свойства сокета (тип, семейство, протокол) будут установлены в значения по умолчанию»: это было изменено в Python 3.7 github.com/python/cpython/blob/…

Jacques Gaudin 25.04.2018 17:15

Бенджамин, не могли бы вы рассказать, как вы это обнаружили? Сам по себе ответ действительно крутой, но читатели также могут извлечь уроки из вашей цепочки гипотез и проверок.

void 26.04.2018 22:55

@void: Бен обнаружил проблему, изучив исходный код Python для создания сокета. (Я работаю с Беном; я не экстрасенс. :-)

RichieHindle 08.05.2018 11:37

Другие вопросы по теме