I have an unity3d client using BeginConnect to connect my local server, but the connection can not be established randomly, espacially after I restart the unity editor. Once it connected, it will become quite normal even I restart the game(not the editor) many times.
The wireshark shows that nothing are sent when issue occures.
I have another very similar client but it can connect to my another similar local server very perfectly.
Any idea what caused the problem?
Thanks in advance.
===
PS.
Even with a retry mechanism the client can connect to server succssfully but the later async operations(BeginSend & BeginReceive) may still randomly stop working.
The connect may be unresponsive even I ran the client without runing the server.
I have code to close the socket in the OnApplicationQuit() function:
socket.Shutdown(SocketShutdown.Both);
socket.Close();
Another similar client has almost the same codebase but works very well.
I found another similar issue: http://answers.unity3d.com/questions/925955/socketbeginwrite-no-response-in-463f1.html?sort=oldest. but it can't explain why my another client(same version of unity) works.
Most of our TCP related problems were related to failing to close the listener thread or failing to disconnect from server.
When you create a thread in editor environment, the thread will continue to exist as long as the editor runs, even if you stop the game. If you use TCP in a multithreaded way, you have to manually stop the thread in some OnDestroy or OnDisable methods.
Also make sure you disconnect from server when you stop the game.
If these were not enough to solve your problem, then I may be able to help if you can share some example code that causes this problem.
According to this http://answers.unity3d.com/questions/925955/socketbeginwrite-no-response-in-463f1.html?sort=oldest, it seems that in unity3d v4.6.3f1, the mono runtime has some bugs in the implementation of BeginXXX series functions.
The unity team may fixed these bugs in newer version(not tested), but I still need to stay on v4.6.3f1, so the workaround is replacing the BeginXXX with XXXAsync series. (tested and works for my problem)
Related
I am simply looking at the sample code found here:
When I run the server portion and start multiple instances of the client I notice that when I start around 40-50 of them at the same time (using Process.Start()) that sometimes some clients fail to connect.
Why does this happen? What actually stops all these clients from connecting at once? Is there a request limit hidden somewhere?
Are you sure the limitation is not on the server?
I use ClientWebSocket to do some simplistic stress test on my WebSocket component and I can reach thousands or connections and almost a 100% throughput of my NIC. However, I do not create a process for each call. You can see the test console app source code or just download the executable here.
I have a small client/server application. I was using a hand-coded TCP connection to allow the client to control the server, but now I've converted it to WCF. This saved me a whole bunch of code, but it also gave me a whole new set of problems to fix...
The latest problem is that after a while, the server disconnects the client. I do not want this to ever happen, under any circumstances. Currently the client gets about a quarter of the way through its run, and then explodes with fire because the server has dropped the connection. I need to stop this happening.
I was able to write a trivial WCF client/server pair that replicates the problem. It seems that if the client calls a method, waits 15 minutes, and then calls a second method, the second call throws an exception babbling something about the socket having been closed. If I reduce the delay, everything works fine.
I read in another answer somewhere that setting ReceiveTimeout should fix this. However, when I tried it, this only fixes the problem under .NET; when running under Mono, it still breaks. Since Mono is the actual target platform, this isn't very helpful.
(Think about SSH - you would not want an SSH server to disconnect you just because you didn't type anything for a while. Perhaps you issued a long-running shell command or something... Just because the server hasn't received any data from you doesn't mean nothing is happening! It certainly doesn't mean your connection should get dropped...)
All code is C#. The server is a self-hosting console app. The client is also a console app. All configuration is in code. Binding is NetTcpBinding with default settings.
What can I do to allow the client to run to completion successfully?
I have a few ideas, but none of them are pretty:
Manually send heartbeat messages. (Yuck!)
Detect disconnection and automatically reconnect? (Again, yuck.)
Turn on "reliable mode". (I'm guessing that since the server deliberately ends the session, this won't help.)
Create one connection per method call. (That's going to be quite a lot of code...)
Stop using WCF?
In the end I "fixed" this by having the client make a new connection for every single command. This works acceptably because the client doesn't send commands all that often. It's annoying having to write the connect/disconnect code a dozen times though...
I have written a sample client and server. The server keeps on listening while client connects, sends requests and then disconnects. I have a scenerio when the client connects to the server and before sending requests the server is shutdown forcefully or by any means. My question is how can I handle this? Can I keep the server from disconnecting unless it notifies its connected clients? Can I write such a method? How?
EDIT: by server and client i mean server and client applications I have written my self
Thanks
Please clarify your situation. The
server
means your server application or the physical server itself? If the server means the o/s itself, then nothing you can do except to perform a thorough software and hardware troubleshooting.
UPDATE:
Ok, if that is your application problem, then you can try to implement Try..Catch statement in your code and learn more for the exception being raised.
The point is that, you must prevent an exception in the first place rather than seeking solution when exception happens.
Since you are in control for both server and client application, you can use a comet approach to monitor the server application status, ie the server still running, or had shutdown.
For more information about the concept of comet approach, here is the link: http://www.codeproject.com/KB/aspnet/CometAsync.aspx
Unfortunate short answer: no. Lots of things can forcefully and unexpectedly shut down your server -- whether it be a network error, a system administrator, or a state-wide power failure.
The best you can do is ensure your client is able to handle sudden server disconnections.
I don't think there is anything you can do if the server is forcefully shut down. The best you can do is make sure the client checks to make sure the server is still up before it sends any commands. This will at least prevent the client from crashing.
If your client is always connected and able to receive commands from the server there is nothing stopping you from sending some kind of command to the client if the server is shut down in an orderly fashion.
I have a C# application that has been running fine for several years. It connects via a TCP/IP socket to a machine that sends me stock trade executions.
Recently, I've tried to deploy it to some machines in a new data center that is behind a hardware firewall, and I've started to see some weird dis-connects.
When a dis-connect happens, in my app (the client side), I see nothing unusual except that I stop receiving data over the socket. Wireshark confirms that no data is reaching the socket and my application's receive thread is blocking on the Receive() call when I stop it in the debugger. The socket shows as ESTABLISHED in netstat.
But from the server side, it looks like my client is dis-connecting. Looking at their logs, it looks like the socket on their end usually ends up with either (nRecvd=-1,errno=104) or (nRecvd=0,errno=11). (104 is connection reset by peer).
The dis-connect only seems to happen after a period of in-activity. I have solved this for now by implementing a heartbeat between my client and their server that just sends a short message every 20 seconds and gets a reply. This has caused the dis-connects to drop to 0 over the past few days.
At first, I figured that the hardware firewall was the problem. It was causing the socket to time out after in-activity. But the person in charge of the firewall claims that the timeout for connects on this port (8887) is 2160 minutes.
I am running Windows Server 2003 and .NET 3.5. The trades server is a linux machine (sles9 I believe though I'm not sure).
Any ideas on what might be going on? What could I do to debug this more given that I don't have any access to the firewall logs and no ability to change the code on the trade server?
Thanks,
Mike
What you describe is common, and it's common to implement a heartbeat to keep TCP sockets alive through such firewalls/gateways like you did.
That hardware might have hard 2160 minutes timeouts (in my experience 20-30 minutes is more common though) , but connections are usually dropped much more aggressively if there's any kind of load. Such firewalls have limited resources, and when they need more connection tracking they tend to drop the oldest connection tracked without any activity regardless of the hard timeout set.
If you want to debug this more, go sniff on the server side of the firewall and see what , if anyting, happens when the server gets a disconnect
I would setup wiresharp on both sides of the firewall to see what happens on TCP (and lower level).
And when the admin says the "timeout for connects" is something. Is that the timeout for an idle, established connection? Anything else does not make any sense I guess.
Also, are you using KeepAlive option for TCP? And is that forwarded by the firewall or not?
As I said, probably want to run wireshark on both sides of the firewall...
I've written a client/server model in C# using .Net remoting. If I have the client connected to the server, then kill the server and restart it without trying to call any server methods from the client whilst the server is down, I can reconnect happily.
If I close the server then try to ping the server from the client (which I do from a separate thread to avoid an endless wait) then when the server comes back online, the client can never talk to it and my Ping thread that was fired during the downtime waits forever deep in the guts of the remoting libraries. I try to Abort this (if trying to Join the thread fails after a short time) but it won't abort. I'm wondering if this is part of the problem.
If I start up another client, then that client can talk to the server just fine. I figured I needed to restart some aspect of the original client but cannot see what would need to be shut down. I certainly null the server I'm connected to and call Activator.GetObject with the same address (something the second client does to connect to the server, which works fine), but re-getting the server doesn't help at all.
The server is running a as singleton via RegisterWellKnownServiceType.
I would start with wireshark and use it to see what is really going across the wire.
Is .NET remoting a requirement, or could you consider moving to WCF instead? The protocols are better factored and more clearly exposed when needed.
I was solving a similar problem. I had a working .NET remoting application using configuration files for the remoting and the routines of the .NET remoting I had to integrate into a larger application. I integrated this into the larger project, by the Activator.GetObject returned an instance of the proxy. As soon as there was a call of a member from the proxy instance, it ended up inside the member call and could not get off. The larger application contained various configuration files already thus the .NET remoting configurations I placed right there along with another configs for another thihs, and there was the crux of the matter. After I placed the .NET remoting configurations into a new empty config(s) file, the .NET remoting in the larger application started to work.