AsyncIO
AsyncIO copied to clipboard
SocketException when creating one of the NetMQ Sockets on Windows with Mono
Consider the following code:
var socket = new RequestSocket();
socket.Connect("tcp://localhost:32700")
On Linux this works fine with Mono On Windows this works fine with .NET But on Windows this crashes with Mono
at AsyncIO.Windows.Socket.SetSocketOption
The first response might be: Just use .NET on Windows but I am using NetMQ in the Godot game engine. When you export your "game" it bundles Mono so it always targets and not .NET.
In other words AsyncIO/NetMQ works great in Godot on Linux, not so much on Windows.
Unhandled Exception:
System.Net.Sockets.SocketException (0x80004005): An invalid argument was supplied.
at AsyncIO.Windows.Socket.SetSocketOption (System.Net.Sockets.SocketOptionLevel optionLevel, System.Net.Sockets.SocketOptionName optionName, System.Int32 optionValue) [0x00018] in <3c72113274de4b3face0e2579126a901>:0
at AsyncIO.AsyncSocket.set_NoDelay (System.Boolean value) [0x00000] in <3c72113274de4b3face0e2579126a901>:0
at NetMQ.Core.Transports.Tcp.TcpConnector.OutCompleted (System.Net.Sockets.SocketError socketError, System.Int32 bytesTransferred) [0x00051] in <21696b85a92a4a0eb8332ff57aebfd69>:0
at NetMQ.Core.Transports.Tcp.TcpConnector.StartConnecting () [0x00097] in <21696b85a92a4a0eb8332ff57aebfd69>:0
at NetMQ.Core.Transports.Tcp.TcpConnector.ProcessPlug () [0x0001b] in <21696b85a92a4a0eb8332ff57aebfd69>:0
waiting
at NetMQ.Core.ZObject.ProcessCommand (NetMQ.Core.Command cmd) [0x0007a] in <21696b85a92a4a0eb8332ff57aebfd69>:0
at NetMQ.Core.IOThread.Ready () [0x00016] in <21696b85a92a4a0eb8332ff57aebfd69>:0
at NetMQ.Core.IOThreadMailbox.RaiseEvent () [0x00008] in <21696b85a92a4a0eb8332ff57aebfd69>:0
at NetMQ.Core.Utils.Proactor.Loop () [0x00050] in <21696b85a92a4a0eb8332ff57aebfd69>:0
at System.Threading.ThreadHelper.ThreadStart_Context (System.Object state) [0x00014] in <e04d3ec971c54d368992eafd86c45930>:0
at System.Threading.ExecutionContext.RunInternal (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx) [0x00071] in <e04d3ec971c54d368992eafd86c45930>:0
at System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx) [0x00000] in <e04d3ec971c54d368992eafd86c45930>:0
at System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state) [0x0002b] in <e04d3ec971c54d368992eafd86c45930>:0
at System.Threading.ThreadHelper.ThreadStart () [0x00008] in <e04d3ec971c54d368992eafd86c45930>:0
[ERROR] FATAL UNHANDLED EXCEPTION: System.Net.Sockets.SocketException (0x80004005): An invalid argument was supplied.
at AsyncIO.Windows.Socket.SetSocketOption (System.Net.Sockets.SocketOptionLevel optionLevel, System.Net.Sockets.SocketOptionName optionName, System.Int32 optionValue) [0x00018] in <3c72113274de4b3face0e2579126a901>:0
at AsyncIO.AsyncSocket.set_NoDelay (System.Boolean value) [0x00000] in <3c72113274de4b3face0e2579126a901>:0
at NetMQ.Core.Transports.Tcp.TcpConnector.OutCompleted (System.Net.Sockets.SocketError socketError, System.Int32 bytesTransferred) [0x00051] in <21696b85a92a4a0eb8332ff57aebfd69>:0
at NetMQ.Core.Transports.Tcp.TcpConnector.StartConnecting () [0x00097] in <21696b85a92a4a0eb8332ff57aebfd69>:0
at NetMQ.Core.Transports.Tcp.TcpConnector.ProcessPlug () [0x0001b] in <21696b85a92a4a0eb8332ff57aebfd69>:0
at NetMQ.Core.ZObject.ProcessCommand (NetMQ.Core.Command cmd) [0x0007a] in <21696b85a92a4a0eb8332ff57aebfd69>:0
at NetMQ.Core.IOThread.Ready () [0x00016] in <21696b85a92a4a0eb8332ff57aebfd69>:0
at NetMQ.Core.IOThreadMailbox.RaiseEvent () [0x00008] in <21696b85a92a4a0eb8332ff57aebfd69>:0
at NetMQ.Core.Utils.Proactor.Loop () [0x00050] in <21696b85a92a4a0eb8332ff57aebfd69>:0
at System.Threading.ThreadHelper.ThreadStart_Context (System.Object state) [0x00014] in <e04d3ec971c54d368992eafd86c45930>:0
at System.Threading.ExecutionContext.RunInternal (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx) [0x00071] in <e04d3ec971c54d368992eafd86c45930>:0
at System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx) [0x00000] in <e04d3ec971c54d368992eafd86c45930>:0
at System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state) [0x0002b] in <e04d3ec971c54d368992eafd86c45930>:0
at System.Threading.ThreadHelper.ThreadStart () [0x00008] in <e04d3ec971c54d368992eafd86c45930>:0
I have a walk around:
AsyncIO.ForceDotNet.Force();
and
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
NetMQConfig.Cleanup(false);
}
are the solution.
Working example:
using Godot;
using NetMQ;
using NetMQ.Sockets;
namespace RPG
{
public class Main : Node2D
{
private ResponseSocket _server = null!;
private RequestSocket _client = null!;
public override void _Ready()
{
AsyncIO.ForceDotNet.Force();
_server = new ResponseSocket("@tcp://localhost:5556");
_client = new RequestSocket(">tcp://localhost:5556");
_client.SendFrame("assss");
GD.Print(_server.ReceiveFrameString());
}
public override void _Process(float delta)
{
}
public override void _Input(InputEvent @event)
{
if (@event.IsActionPressed("quit"))
{
GetTree().Quit();
}
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
NetMQConfig.Cleanup(false);
}
}
}
I will try this, thank you @KrunoSaho