Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exception from a background thread when socket is disposed while receiving a message #14

Open
msykora opened this issue Apr 25, 2017 · 2 comments

Comments

@msykora
Copy link

msykora commented Apr 25, 2017

Hello,

I am using NetMQ 3.3.3.4 and this is crashing my whole application as it cannot be catched running poller async on a background thread. It happens when the other side closes their socket just as a message comes in, but also when a firewall blocks outgoing connections, etc. I think the socket should handle it gracefully and not throw an unhandled exception... Code to reproduce this easily(doesn't happen 100% o the time but most of the time, probably some timing issue, sometimes a nullreference is thrown instead):

        using (poller = new NetMQPoller()) {
            poller.RunAsync();
            using (NetMQSocket server = new RouterSocket(), client = new RouterSocket()) {
                var serverId = Encoding.UTF8.GetBytes("server");
                server.Options.Identity = serverId;
                server.Bind(address);
                server.ReceiveReady += (sender, revents) => {
                        var msg = revents.Socket.ReceiveMultipartBytes();
                        Console.WriteLine("msg received:" + Encoding.UTF8.GetString(msg[2]));
                    };
                poller.Add(server);

                client.Options.DelayAttachOnConnect = true;
                client.Connect(address);
                Console.WriteLine("sending: " + client.TrySendFrame(serverId, true));
                server.Dispose();
                Thread.Sleep(500);
                Console.WriteLine("all done, press enter to end");
                Console.ReadLine();
            }

Here is the exception:
System.Net.Sockets.SocketException occurred
HResult=0x80004005
Message=An existing connection was forcibly closed by the remote host
Source=System
StackTrace:
at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
at NetMQ.Core.Mailbox.TryRecv(Int32 timeout, Command& command)
at NetMQ.Core.SocketBase.ProcessCommands(Int32 timeout, Boolean throttle)
at NetMQ.Core.SocketBase.GetSocketOption(ZmqSocketOption option)
at NetMQ.Core.Utils.Selector.Select(SelectItem[] items, Int32 itemsCount, Int64 timeout)
at NetMQ.NetMQPoller.Run()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()

Would it be possible to fix this?

Thanks,
Martin

@somdoron
Copy link
Contributor

In the example, you are accessing the server socket from multiple threads, which is what causing the exception. You call dispose on the server from one thread but the server socket is also being used in the poller thread. First remove the server socket from the poller and then call dispose.

@msykora
Copy link
Author

msykora commented May 3, 2017

:( I tried to get some simple replication example and didn't get it right... The fact is, in real case my client is connecting to a remote ZMQ socket(JeroMQ implementation) and they close their socket it seems while my socket is trying to receive a message, and my whole application crashes on the aforementioned exception...
BTW the same happens if firewall suddenly block outgoing connections, an exception from a background thread... And in this real use case I am running dispose etc. from the poller thread and handlign received messages the same way through receiveready... I can't easily provide simple code to replicate that, but it really is happening... can you help?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants