PacketID: 27715

05/13/2014 22:25 Y u k i#1
Code:
18 00 F2 03 F9 FD A3 19 63 42 0F 00 00 00 00 00 00 00 00 00 00 00 72 00 54 51 43 6C 69 65 6E 74 18 00 F2 03 FA FD A3 19 63 42 0F 00 00 00 00 00 00 00 00 00 00 00 4B 00
Quote:
òáA¨cBrTQClientòáA¨cBK
PacketID: 27715
Size: 56

Offset 8 - Character UID
Offset 34 - 1010 (MsgAction?)


Packet does NOT change. Always sending the exact same bytes on LOGIN.
Echoing back to the client results in a DC not in a client close.

Anyone knows anything about it?


Oh yeah, packets can be sent in chunks... thats what I get for not implementing a split packet handler..

TCP/IP y u do this to me?
05/13/2014 22:36 Korvacs#2
Looks like its 2 packets to me that haven't been split correctly, given the length is 24 for both packets. Oh and the type is 1010 in both cases.
05/13/2014 22:39 Y u k i#3
Quote:
Originally Posted by Korvacs View Post
Looks like its 2 packets to me that haven't been split correctly, given the length is 24 for both packets. Oh and the type is 1010 in both cases.
Yeah, just figured that out myself haha... wow.. embarassing. Thanks tho jack!
05/14/2014 09:00 jackpotsvr#4
Sad, no undiscovered packet was found that day ;p
05/14/2014 11:33 Korvacs#5
Oh and its TCP/IP.
05/14/2014 11:36 -impulse-#6
Yuki, when implementing a packet splitter you might want to enqueue everything you get and then split from the top and not directly what you get from the receive function. On localhost it won't make a difference but on the Internet it will.
05/14/2014 11:41 Korvacs#7
Oh and a packet ID of 27715? You realise thats 'Cl' from 'TQClient' right? How on earth did you pull the packet ID from that part of the packet?
05/14/2014 13:16 CptSky#8
Packet buffering is not only part of TCP/IP. Anyway, you need a packet splitter, but also you need to handle packet fragmentation, which is something else.
05/14/2014 15:32 Y u k i#9
Quote:
Originally Posted by Korvacs View Post
Oh and a packet ID of 27715? You realise thats 'Cl' from 'TQClient' right? How on earth did you pull the packet ID from that part of the packet?
Well I got a receive loop and it always reads the 2nd offset as a Int16.

Code:
for (int Counter = 0; Counter < Recv.Length; Counter += Size)
                    {
                        Size = BitConverter.ToUInt16(Recv, 0);
                        ushort Type = BitConverter.ToUInt16(Recv, 2);
                        if (Size != Recv.Length)
                        {
                            byte[] Chunk = new byte[Size];
                            Buffer.BlockCopy(Recv, Counter, Chunk, 0, Size);

                            ThreadPool.QueueUserWorkItem(O =>
                            {
                                PacketHandler.HandlePacket(Client, Type, Chunk);
                            });
                        }
Well, I guess we all see why it doesnt work dont we?
05/14/2014 19:47 SteveRambo#10
Quote:
Originally Posted by Y u k i View Post
Code:
for (int Counter = 0; Counter < Recv.Length; Counter += Size)
                    {
                        Size = BitConverter.ToUInt16(Recv, 0);
                        ushort Type = BitConverter.ToUInt16(Recv, 2);
                        if (Size != Recv.Length)
                        {
                            byte[] Chunk = new byte[Size];
                            Buffer.BlockCopy(Recv, Counter, Chunk, 0, Size);

                            ThreadPool.QueueUserWorkItem(O =>
                            {
                                PacketHandler.HandlePacket(Client, Type, Chunk);
                            });
                        }
Well, I guess we all see why it doesnt work dont we?
You do realize it's a terrible idea to use more than a single thread for packet processing, right? I'm talking about your usage of the ThreadPool class.
05/14/2014 20:05 Spirited#11
Quote:
Originally Posted by SteveRambo View Post
You do realize it's a terrible idea to use more than a single thread for packet processing, right? I'm talking about your usage of the ThreadPool class.
That's not good advice either though. Multithreading is definitely a good idea for packet processing, but using a ThreadPool from C# is not. Managing your own worker threads and the number of threads processing requests at one given time is optimal. A single thread processing all requests for a server... bad idea.

Edit: Also, I have a packet splitter / fragment handler for my server that should be more or less public on my blog. I think I made modifications to it in my project since posting it on my blog, but it should work as is. Step through the design before implementing it.
05/14/2014 20:10 SteveRambo#12
Quote:
Originally Posted by Spirited View Post
That's not good advice either though. Multithreading is definitely a good idea for packet processing, but using a ThreadPool from C# is not. Managing your own worker threads and the number of threads processing requests at one given time is optimal. A single thread processing all requests for a server... bad idea.

Edit: Also, I have a packet splitter / fragment handler for my server that should be more or less public on my blog. I think I made modifications to it, but it should work as is.
... you might as well just use UDP then, if you don't care in what order your packets are processed :o
05/14/2014 20:14 Spirited#13
Quote:
Originally Posted by SteveRambo View Post
... you might as well just use UDP then, if you don't care in what order your packets are processed :o
TCP sends packets in order, thus the server receives packets in order. For things that need to be processed one at a time, use queues. Processing all packets on one thread is idiotic - it's just going to bottleneck at the packet handler.
05/14/2014 20:23 SteveRambo#14
Quote:
Originally Posted by Spirited View Post
TCP sends packets in order, thus the server receives packets in order.
Player jumps from position 300, 300 to 300, 310 and sends packet A to the server with this information.
Player jumps from position 300, 310 to 300, 320 and sends packet B to the server with this information.

The server receives packet A and B in the correct order, because the server uses TCP.

The server uses a thread pool to process packets, so both packet A and B are submitted to the thread pool for processing.

The server uses thread A for processing packet A and thread B for processing packet B.

While processing packet A in thread A, the operating system suddenly decides to stop thread A before it's done processing and gives thread B time to run.

Thread B happens to complete the processing of packet B and now the operating system gives time for thread A to continue again.

What happens then? The client is going to get disconnected because the server processed the packets in the wrong order: it thinks that the player jumped from 300, 300 to 300, 320 (distance = 20 ==> disconnect).
05/14/2014 21:00 KraHen#15
Quote:
Originally Posted by SteveRambo View Post
Player jumps from position 300, 300 to 300, 310 and sends packet A to the server with this information.
Player jumps from position 300, 310 to 300, 320 and sends packet B to the server with this information.

The server receives packet A and B in the correct order, because the server uses TCP.

The server uses a thread pool to process packets, so both packet A and B are submitted to the thread pool for processing.

The server uses thread A for processing packet A and thread B for processing packet B.

While processing packet A in thread A, the operating system suddenly decides to stop thread A before it's done processing and gives thread B time to run.

Thread B happens to complete the processing of packet B and now the operating system gives time for thread A to continue again.

What happens then? The client is going to get disconnected because the server processed the packets in the wrong order: it thinks that the player jumped from 300, 300 to 300, 320 (distance = 20 ==> disconnect).
This. For the last week I`ve been rewriting the way we handled packets for a rather large project at my job for exactly the same reason.