marceldev89 / BattleNET

BattlEye Protocol Library and Client
GNU Lesser General Public License v3.0
76 stars 44 forks source link

BattleNET and Thread.Sleep #28

Closed DomiStyle closed 11 years ago

DomiStyle commented 11 years ago

Hello, it appears that BattleNET is having problems when using Thread.Sleep for a longer amount of time (for example 30 seconds). And with problems I mean it disconnects and reconnects. I tried using Thread.Sleep() in another thread but it appears that it still affects BattleNET for whatever reason. Sleeping for 10 seconds appears to be fine but 30 seconds makes BattleNET drop the connection and reconnect.

Here is a little example program which will cause BattleNET to disconnect every time it waits for 30 seconds. It is running in a different thread.

static void Main(string[] args)
        {
            BattlEyeClient b;
            BattlEyeLoginCredentials loginCredentials = new BattlEyeLoginCredentials(IPAddress.Parse("127.0.0.1"), 2302, "password");

            b = new BattlEyeClient(loginCredentials);
            b.ReconnectOnPacketLoss = true;
            b.Connect();

            Program p = new Program();
            Thread thread = new Thread(new ThreadStart(p.DisconnectThread));
            thread.IsBackground = true;
            thread.Start();

            while (true)
                Thread.Sleep(1000);
        }

        public void DisconnectThread()
        {
            while (true)
            {
                Console.WriteLine("Waiting 30 seconds...");
                Console.WriteLine("BattleNET will reconnect after about 25 seconds.");
                Console.WriteLine("Check server console for connect messages.");
                Thread.Sleep(30000);
            }
        }
marceldev89 commented 11 years ago

That's quite some odd behavior. But I can't reproduce this (both stable and dev), see screenshot.

http://ziellos2k.net/images/20130313131533964.png

DomiStyle commented 11 years ago

Strange, my output looks like this: http://forum.swisscraft.eu/images/battlenet.PNG Any idea what could cause this?

marceldev89 commented 11 years ago

Hmm maybe it's because of localhost?

DomiStyle commented 11 years ago

I tried from a remote host too.

DomiStyle commented 11 years ago

Tried with the latest dev branch but it still disconnects everytime.

marceldev89 commented 11 years ago

I haven't got a single clue to be honest. :smile:

nanomo commented 11 years ago

a thread mess

marceldev89 commented 11 years ago

the library only uses 2 threads, 1 to receive packets and 1 to keep the connection alive.

DomiStyle commented 11 years ago

I was able to get rid of the problem from a remote host but I still have the problem when it is running on the same host.

marceldev89 commented 11 years ago

What did you do to fix it (kinda)?

DomiStyle commented 11 years ago

I didn't really do anything. Was just messing around with different BattleNET versions and suddenly it started working. However, the server is running Wine. It may be related to that. Will do some more testing with different Wine settings and try on a native windows server.

DomiStyle commented 11 years ago

It appears that BattleNET reconnects in BattlEyeClient.cs on line 346. socket.Connected returns false. I tried to disable the check for socket.Connected and it appears that the connection really gets dropped. After Thread.Sleep is over BattleNET is unable to send a message.

The actual disconnect happens at line 306. I get 4x 5 seconds timeout and the 20 second timeout after that which will cause BattleNET to disconnect.

There is nothing wrong with the timeout though. The connection gets dropped by the server after the timeout anyway.

marceldev89 commented 11 years ago

Can you verify if the library is actually sending the 'keep alive' packets (line 315) during the sleep with wireshark?

DomiStyle commented 11 years ago

It fails at line 315 packetQueue.Count == 0 at the beginning. After the first reconnect it sends a keep alive packet. Still reconnecting though.

Running WireShark now.

DomiStyle commented 11 years ago

Here is the capture from WireShark: http://bounty.swisscraft.eu/battlenet.pcap I removed 2 packages containing the password but left everything else going to port 2302 from IP 127.0.0.1. There is a pretty big gap after sending out the first few messages. In that time no package gets sent till the timeout and reconnect.

marceldev89 commented 11 years ago

It's odd though, I couldn't reproduce it last time. There must be something different on your system.

DomiStyle commented 11 years ago

Well, the server is running under Wine that is the only difference I guess. Can't figure out what could cause something like this though.

marceldev89 commented 11 years ago

The server shouldn't affect client side though, I mean the actual threads and what not are running locally.

You could try creating another thread which sends a null packet every 5 seconds to see if sending packets actually works.

DomiStyle commented 11 years ago

It's really strange. If I run it on the server packetQueue.Count is 2 before first reconnect. When running it locally packetQueue.Count is 0, no reconnect here.

marceldev89 commented 11 years ago

Did you try this?

You could try creating another thread which sends a null packet every 5 seconds to see if sending packets actually works.

DomiStyle commented 11 years ago

I am reinstalling Wine at the moment to see if that solves the problem. After that I will try it.

DomiStyle commented 11 years ago

Ok, another update on this: It appears that commands get stuck in packetQueue which causes everything to get stuck and stop working. If I send a command on connect it gets sent to the server but still appears in packetQueue - the client gets stuck and reconnects all the time. But if I do not send a command I stay connected till the first command gets sent. So the packages are stuck in packetQueue but also do not get sent to the server, which they shouldn't anyway because they already got sent but not removed from packetQueue.

marceldev89 commented 11 years ago

That's somewhat intended behavior. The command is only removed from the queue when the client receives a response from the server.

DomiStyle commented 11 years ago

It does indeed stay connected if I send the keep alive package everytime. From what I have seen I do receive an answer from the server?

marceldev89 commented 11 years ago

Could you pm me the server info?

DomiStyle commented 11 years ago

Sent you the login info. Not sure if it will do the same if not running on the server itself though.

marceldev89 commented 11 years ago

Oh missed the fact that you're running BattleNET server side. Are you using native mono or wine .net?

DomiStyle commented 11 years ago

Wine .NET 4.0

marceldev89 commented 11 years ago

If you don't need a gui try it with 'native' mono or if you do need a gui try it with mono for wine.

DomiStyle commented 11 years ago

It seems like the issue got resolved with the new version. However, now a few messages get sent 2 times. Running it with Mono didn't really make any difference.

DomiStyle commented 11 years ago

I removed the packet resent at line 324 but left in the package removal the line after that to prevent BattleNET from disconnecting. Seems to work for now. And since it's running on the same host I wouldn't expect any packet lost.

marceldev89 commented 11 years ago

I guess that's better than doing what it did before. :smile:

What's the time between the first and duplicated message?

DomiStyle commented 11 years ago

It depends on what I set on line 322. If I set 2 seconds it gets sent again after about 2 seconds. If I set 5 seconds it gets sent again after about 5 seconds.

marceldev89 commented 11 years ago

And this is all the time?

DomiStyle commented 11 years ago

Not all the time but like every second message I send.

marceldev89 commented 11 years ago

So basically: you send a message => server responds with message => library sends the same message => server responds with message?

DomiStyle commented 11 years ago

Yes, after the message got sent a second time it gets removed from packetQueue. Will need to check again via WireShark to see if the server really responds but I see no reason why it shouldn't.

marceldev89 commented 11 years ago

Well if the response arrives before 2 seconds it should just work. There isn't much that could go wrong library wise.

marceldev89 commented 11 years ago

Please continue here regarding the sending command twice.