I’m trying to use the Windows API to set the reusable address option on a UDPSocket. However I’m getting a “WSAENOTSOCK 10038” error suggesting that the socket handle is invalid. The socket object has been created and handle is a non-0 value at the time of the call.
Sample code is below. Does anyone have any ideas as to what might be wrong?
#If TargetWindows Then
// Constants
Const SOCKET_ERROR = -1 ' error return
Const SOL_SOCKET = 65535 'socket level option
Const SO_REUSEADDR = &H4 'reuse address option
// Windows API Declares
Soft Declare Function setsockopt Lib "Ws2_32.dll" (s As Integer, level As Int32, optname As Int32, ByRef optval As Int32, optlen As Int32) As Int32
Soft Declare Function WSAGetLastError Lib "Ws2_32.dll" () as Int32
// Set Option
dim tBool as Int32 = 1
dim lResult as Integer = setsockopt(sock.Handle,SOL_SOCKET,SO_REUSEADDR,tBool,4)
If lResult = SOCKET_ERROR Then
dim iError as Int32 = WSAGetLastError
End If
#EndIf
Try to use a Ptr instead of an integer, or it may become an invalid handler value.
#If Target64Bit Then
Soft Declare Function setsockopt Lib "Ws2_32.dll" (s As Ptr, level As Int32, optname As Int32, ByRef optval As Int32, optlen As Int32) As Int32
#Else
Soft Declare Function setsockopt Lib "Ws2_32.dll" (s As Integer, level As Int32, optname As Int32, ByRef optval As Int32, optlen As Int32) As Int32
#EndIf
Soft Declare Function WSAGetLastError Lib "Ws2_32.dll" () As Int32
Additionally the following may be needed:
Dim lResult As Integer
#If Target64Bit Then
lResult = setsockopt(Ptr(sock.Handle), SOL_SOCKET, SO_REUSEADDR, tBool, 4)
#Else
lResult = setsockopt(sock.Handle, SOL_SOCKET, SO_REUSEADDR, tBool, 4)
#EndIf
I couldn’t get it working with your solution so I had another look and the Handle value of the UDPSocket is always &hFFFFFFFF until Connect is called, so Xojo must not actually create the socket until you make this call.
I’m fairly sure you have to set the “reuse” option before binding the port though. So If Xojo doesn’t expose a valid handle at this point then it looks like this makes it impossible to achieve what I’m after…
I’m not sure how MBS does it but I don’t want to rely on an external plugin as it’s just this one function I need. Also needed to find code for the equivalent call on Mac and Linux once Windows is working
Appreciated I can… however as stated above, I wanted to avoid a plugin based solution.
I’m potentially thinking about releasing what I’m making for other developers to use in their own apps, so I don’t want to force them to use a plugin that’s going to cost them money.
I think I might raise this in Issues. Seems a pretty fundamental flaw in the implementation given it prevents you doing several things with the socket
I’ve also tried doing Connect, Close, setting reusable port then Connect again. However, I’ve discovered that the handle id changes each time you call Connect, so the underlying socket must be being created fresh each time.