【问题标题】:Failed to close socket handle with ERROR_INVALID_HANDLE (6)使用 ERROR_INVALID_HANDLE (6) 关闭套接字句柄失败
【发布时间】:2018-04-19 07:57:21
【问题描述】:

我在 ctypes 中使用 winsock2 套接字,我可以做 closesocket() 就好了,但调用 CloseHandle,总是导致 ERROR_INVALID_HANDLE (6)。我应该如何正确关闭它?目前我的应用程序在 64 次 socket() 调用后总是崩溃。

# from MSDN:
# BOOL CloseHandle(   HANDLE hObject);

closehandle = coredll.CloseHandle
closehandle.argtypes = [ w.LPVOID ]

SOCKET = c_ulong
socket = ws2.socket
socket.restype = SOCKET
self._clnt_socket = socket(AF_BT, SOCK_STREAM, BTHPROTO_RFCOMM)
...
connect( self._clnt_socket, _psa, sizeof(self._sa) )
...
send( self._clnt_socket, pbuff, szbuff, 0 ) # int send(  SOCKET s,  const char FAR* buf,  int len,  int flags);

SetLastError(0)
rt = closesocket( self._clnt_socket )
ec = GetLastError()
if ec != w.ERROR_SUCCESS :
    print( u'failed to close socket, ec=%s, %s, rt=%s', (ec, FormatError( ec ), rt) )
    raise Exception(u'BT_SOCKET.close.socket %s' % ec)
else:
    print( u'close socket ok' )
#> close socket ok

# from MSDN:
# To close the connection to the target device, call the closesocket
# function to close the Bluetooth socket. Also, ensure that you release
# the socket by calling the CloseHandle function, as the following
# example code shows.  
#
# closesocket(client_socket); 
# CloseHandle((LPVOID)client_socket);

SetLastError(0)
rt = closehandle(  w.LPVOID( self._clnt_socket ) )
ec = GetLastError()
if ec != w.ERROR_SUCCESS :
    print( u'failed to close handle, ec=%s, %s, rt=%s ', (ec, FormatError( ec ), rt) )
    # //Perform error handling.
    raise Exception(u'BT_SOCKET.close.handle %s' % ec)
else:
    print( u'close socket ok' )
#> failed to close handle, ec=6

【问题讨论】:

    标签: python windows-ce ctypes winsock2


    【解决方案1】:

    HANDLEs和SOCKETs是不同类型的objects,所以它们是不兼容的(适用于它们的Python 包装器)。

    [MS.Docs]: CloseHandle function 声明如下:

    不要使用 CloseHandle 函数来关闭套接字。相反,使用closesocket 函数,它会释放与套接字关联的所有资源,包括套接字对象的句柄。如需更多信息,请参阅Socket Closure

    @EDIT0

    作为一个附带问题:您为什么使用 ctypes 而不是 [Python 3]: socket - Low-level networking interface,它是 WinSock 的包装器?这就像在自己的脚上开枪一样。如果 BT 套接字的工作方式与其他套接字相同(例如网络),您唯一需要做的就是定义一些常量(例如 BTHPROTO_RFCOMM)。

    【讨论】:

    • 好的,我认为你是对的,在清理了关闭手柄的东西之后。我可以在不崩溃的情况下打开/写入/关闭套接字超过 64 次,尽管它违反了这个 (docs.microsoft.com/en-us/previous-versions/windows/embedded/…) MSDN artical 建议的...至于 python 套接字,我不知道,如果 python 会检查参数并阻止我使用未知参数?我会试试的,如果可行,那肯定很棒。
    • 啊,我一直忘记这个 WindowsCE 及其局限性。但是在SOCKET 上调用CloseHandle 似乎很奇怪,因为在64 位上它的大小比HANDLE 更大。
    • 感谢您的调查。我已经尝试过python套接字,但无法连接。 socektconnect() 方法既不接受我的 bt 地址,也不接受 int('dc1d30428b19',16)'dc1d30428b19''dc:1d:30:42:8b:19'。我猜模块必须打补丁。但我已经克服了主要的障碍,现在它有点稳定了; unicode 工作正常;现在我可以专注于 GUI,我希望它适用于线程。再次感谢您的帮助。
    • 是的,Python 的包装器需要一个包含主机名和端口的元组(字符串,整数)。
    猜你喜欢
    • 2011-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-14
    相关资源
    最近更新 更多