Can't try catch UpdateAsyncEvents()

Monkey Forums/Monkey Programming/Can't try catch UpdateAsyncEvents()

sereschkin(Posted 2015) [#1]
Currently I am fighting with sockets. Everything works like expected. I won't post any code. I just want to know how to make things right.

Short story: I can't find a command like socket.Disconnect() oder Close() or anything (1st wrong assumption). As a result of this sometimes it happens that the server crashes if client was shut down the hard way (i.e. with task manager).

I tried to surround UpdateAsyncEvents() with a try catch block, but it does not help (2nd wrong assumption). It just crash, and to my surprise do it so badly that I have to restart my comp to continue work, because after such a crash TED does not start any more O_o'.

Now I do not know any further. Please help. What is the right way to solve such a socket problem?


ImmutableOctet(SKNG)(Posted 2015) [#2]
O_O - I think this might be a matter of Mark forgetting to document the 'Close' method of 'Socket'. You're supposed to just call 'Close' when you're done. I'm not sure if there's some kind of asynchronous version, though. If there is, maximum compatibility would be achieved by keeping it asynchronous. From what I know, there isn't, though. You should just be able to write your own code for proper disconnection, then when that process is done, you simply close the socket ("Socket.Close()"). And of course, you'll need to make a timeout system for improper disconnections, but you get the idea.

If something's undocumented, you can look at the source code of its module ('brl.socket').

As for 'UpdateAsyncEvents', the following demo works:


The "Test.png" file can be whatever you want.

That will catch the exception without any problems.


sereschkin(Posted 2015) [#3]
Ooops, Thank you. Haven't thought of that. Shame on me.




ImmutableOctet(SKNG)(Posted 2015) [#4]
You're face-palming? I just took an insane amount of time debugging a module where I accidentally wrote some C++ code that used a union, when I thought I was using a structure. It ended up turning my images gray. That's what happens when I program late at night.

And the 'Close' thing is weirdly undocumented, so you shouldn't feel bad about not realizing it. Don't know what that exception thing was about, though.


sereschkin(Posted 2015) [#5]
I'm ashamed :). I thought with the help of try catch I could, well, catch the thrown errors (bus error, bad instruction, memory access violation, some other random messages due to sudden disconnect), because I didn't know how to handle disconnects. I still cannot explain to my self the behavior of try catch in this situation. In my humble opinion a try catch block should catch every exception, but it does not, so I was lost. Thanks for helping out. Excuse me for being not precisely and for not speaking understandable english :P.


sereschkin(Posted 2015) [#6]
I found the solution (beside discovering the close method :) ) for my problem. If there is an async operation running on another thread it is wise to remove this object from async event source first and then close the socket. Everything else will result in a bus error, or in a MAV. At least this is true for my code :| .

Another problem: I've only found to declare a client's connection as invalid or disconnected if remote address is 0.0.0.0:0, though this is not the same as disconnected. But for some reasons the IsConnected property is always true. Im my opinion that shouldn't be the case if connection gets broken.


ImmutableOctet(SKNG)(Posted 2015) [#7]
Are you using UDP or TCP? It's been a while since I've messed with the official socket stuff, so I may not be too much of a help.


sereschkin(Posted 2015) [#8]
I use TCP. You know pretty much about every topic here in the forum, so you are always a help :D .


ImmutableOctet(SKNG)(Posted 2015) [#9]
So, how do you check if someone's disconnected? The answer is pretty awful, and it's not Mark's fault. When 'Receive' is called (Or technically, ReceiveAsync's underlying 'Receive'), the operating system will retrieve what's on the network stack. The thing is, if no message (packet) is available, then it will poll (Wait) until it gets a packet. The only exception to this rule is if a socket is disconnected. If we're talking about UDP, then this is normally very rare, and you'd be using a single host-socket, anyway. UDP handles "connections" differently, and they're not used very often, as they're not as nice as TCP for this kind of thing. It's better to keep UDP connectionless, or to roll your own. But for TCP, you're dealing with sockets for each connection, meaning if that socket becomes disconnected as defined by TCP's standards (There are several, if you're interested), then the operating system will stop polling, and your program using 'Receive' (Either on another thread with 'ReceiveAsync', or on the main thread using a blocking setup) will continue. Since we use this setup, the only proper solution is to have the OS tell the user that nothing was received (Through the return-value). In other words, a socket is disconnected when the packet's length (As described by 'Receive') is zero.

So basically, if you're using the asynchronous functionality, you'd do this:


That was taken from the "echoserver_tcp.monkey" example, I just made it cleaner. This design works for both servers, and clients (Technically, but you may need to add to this). But, since Monkey's "state" setup for 'IsConnected' and similar properties gets changed when 'Close' is called, the end result is 'IsConnected' being 'False'. This means that you should still be checking against that (What you seemed to be doing), but you need to close the connection via 'OnReceiveComplete' first. You could also set up your own system for this, instead of keeping the 'Socket' around, but you get the idea.

That should fix your problem. Checking against the address isn't a good idea for this.