UDPSocket - Invalid Socket handle with API call

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

Because sock.Handler gives back an integer.

1 Like

This is the problem: The socket handle does not yet exist when you try to call setsockopt.And the Xojo UDPSocket doesn’t seem to support SO_REUSEADDR.

If you have the MBSPlugIns maybe the UDPSocket.OptionReusePortMBS option can help?

I think you may be correct.

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

You could use the socket classes in MBS Xojo Plugins instead of Xojo’s.
It’s just an alternative implementation with a few more features.

See UDPSocketMBS class.

1 Like

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

As a workaround, try executing Socket.Listen and see if that gives you a valid handle. If so, you can use your Declares before doing Socket.Connect.

UDPSocket doesn’t have a Listen method

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.