Register for your free account! | Forgot your password?

Go Back   elitepvpers > MMORPGs > Conquer Online 2 > CO2 Programming
You last visited: Today at 10:09

  • Please register to post and access all features, it's quick, easy and FREE!

Advertisement



Handling TCP Packet Fragmentation.

Discussion on Handling TCP Packet Fragmentation. within the CO2 Programming forum part of the Conquer Online 2 category.

Reply
 
Old   #1
 
Danial Eugen's Avatar
 
elite*gold: 0
Join Date: Sep 2012
Posts: 171
Received Thanks: 68
Handling TCP Packet Fragmentation.

Well after long time digging Network programming, one topic remains ambiguous to me. Packet Fragmentation, as far as i know TCP may not give you the message you sent as a whole but might fragment or rebuild it. So there is no guarantee that when i receive for example the Client's Login packet that it would be Full so how in all the source around here From Albetros to Pheonix i can't see any sort of Fragmentation Handling ? does it exists some how and i don't know/understand ?. Please i need a really detailed answer for this topic.
Danial Eugen is offline  
Old 03/07/2014, 00:35   #2
 
TheComputerist's Avatar
 
elite*gold: 0
Join Date: Jun 2012
Posts: 21
Received Thanks: 4
The answer is within the API I believe. In the WinSock API there's a function named recv and it returns the number of bytes received, if the number of bytes don't add up to the number of bytes expected to receive then recv again. Does that help or?
TheComputerist is offline  
Thanks
1 User
Old 03/07/2014, 01:07   #3
 
Spirited's Avatar
 
elite*gold: 12
Join Date: Jul 2011
Posts: 8,282
Received Thanks: 4,190
Project Phoenix does have fragmentation handling. I would encourage that you look over the source again.
Spirited is offline  
Old 03/07/2014, 02:06   #4
 
Danial Eugen's Avatar
 
elite*gold: 0
Join Date: Sep 2012
Posts: 171
Received Thanks: 68
Quote:
Originally Posted by Spirited View Post
Project Phoenix does have fragmentation handling. I would encourage that you look over the source again.
This part is a fragmentation Handling ? or you are referring to another part ?

Code:
    if (length == sizeof(PacketHeader) && passport != null)
    {
       ...
    }
Also i don't understand the part of sizeof(PacketHeader) which seems to be always 0 ?

I really need you to explain this to me in a very detailed way (do me that favor please).
Danial Eugen is offline  
Old 03/07/2014, 02:21   #5
 
Spirited's Avatar
 
elite*gold: 12
Join Date: Jul 2011
Posts: 8,282
Received Thanks: 4,190
Quote:
Originally Posted by Danial Eugen View Post
This part is a fragmentation Handling ? or you are referring to another part ?

Code:
    if (length == sizeof(PacketHeader) && passport != null)
    {
       ...
    }
Also i don't understand the part of sizeof(PacketHeader) which seems to be always 0 ?

I really need you to explain this to me in a very detailed way (do me that favor please).
No, that's basic error checking...
Spirited is offline  
Old 03/07/2014, 02:46   #6
 
Ultimation's Avatar
 
elite*gold: 0
Join Date: Mar 2005
Posts: 1,430
Received Thanks: 1,586
i use a circular buffer, basically everytime i receive the data gets appened to the buffer, Pushed in if u like.

Then when handling the packets i pop the buffer based on the first 2 bytes being the packet length. If the buffer < than the expected length, i know the packet has not yet been fully received. thus wait for it
Ultimation is offline  
Thanks
1 User
Old 03/07/2014, 05:08   #7
 
Spirited's Avatar
 
elite*gold: 12
Join Date: Jul 2011
Posts: 8,282
Received Thanks: 4,190
Quote:
Originally Posted by Ultimation View Post
i use a circular buffer, basically everytime i receive the data gets appened to the buffer, Pushed in if u like.

Then when handling the packets i pop the buffer based on the first 2 bytes being the packet length. If the buffer < than the expected length, i know the packet has not yet been fully received. thus wait for it
That's how my socket system in Phoenix works as well, so he has an example of that available to him. It's not really that complex of a concept.
Spirited is offline  
Thanks
1 User
Old 03/07/2014, 14:28   #8
 
Danial Eugen's Avatar
 
elite*gold: 0
Join Date: Sep 2012
Posts: 171
Received Thanks: 68
Well just a small more thing by waiting for it you mean ? just skip the current Handler ?, and what if i am clearing out the Buffer after each receive (to avoid overlapping ?) ?
Danial Eugen is offline  
Old 03/07/2014, 14:56   #9
 
elite*gold: 21
Join Date: Jul 2005
Posts: 9,193
Received Thanks: 5,379
Quote:
Originally Posted by Danial Eugen View Post
Well just a small more thing by waiting for it you mean ? just skip the current Handler ?, and what if i am clearing out the Buffer after each receive (to avoid overlapping ?) ?
This all happens in your socket system LONG before you handle the actual packet.


When the socket system receives raw data (still encrypted) it decrypts the packets and adds them to a list of waiting bytes (with no concept of how long each packet is or what they represent. It's simply data waiting to be processed by the server)


You can then check the first 2 bytes to check the expected length of the next packet being processed (packet header). If there's not enough bytes to process it (20 packets in queue, packet length of 30) then you simply wait till there are more packets waiting in the buffer.


Clearer?
pro4never is offline  
Old 03/07/2014, 15:26   #10
 
elite*gold: 0
Join Date: Sep 2013
Posts: 197
Received Thanks: 141
Quote:
Originally Posted by pro4never View Post
This all happens in your socket system LONG before you handle the actual packet.


When the socket system receives raw data (still encrypted) it decrypts the packets and adds them to a list of waiting bytes (with no concept of how long each packet is or what they represent. It's simply data waiting to be processed by the server)


You can then check the first 2 bytes to check the expected length of the next packet being processed (packet header). If there's not enough bytes to process it (20 bytes in queue, packet length of 30) then you simply wait till there are more bytes waiting in the buffer.


Clearer?
Np bro!
SteveRambo is offline  
Thanks
1 User
Old 03/07/2014, 16:02   #11
 
Danial Eugen's Avatar
 
elite*gold: 0
Join Date: Sep 2012
Posts: 171
Received Thanks: 68
Quote:
Originally Posted by pro4never View Post
This all happens in your socket system LONG before you handle the actual packet.


When the socket system receives raw data (still encrypted) it decrypts the packets and adds them to a list of waiting bytes (with no concept of how long each packet is or what they represent. It's simply data waiting to be processed by the server)


You can then check the first 2 bytes to check the expected length of the next packet being processed (packet header). If there's not enough bytes to process it (20 packets in queue, packet length of 30) then you simply wait till there are more packets waiting in the buffer.


Clearer?
So something like this ?

Code:
                Socket socket = asynchronousState.Socket;
                int length = socket.EndReceive(ar);
                if (8 <= length) {
                    if (null != ClientReceive) {
                        var bytes = new byte[length];
                        Array.Copy(asynchronousState.Buffer, bytes, length); //Copy data to our local array
                        var packetLength = BitConverter.ToUInt16(bytes, 0); //Read the packet length
                        if (packetLength > length) {
                            //Received bytes is less than expected so start receiving more ?
                            if (socket.Connected) {
                                socket.BeginReceive(asynchronousState.Buffer, 0, packetLength, SocketFlags.None, HandleAsyncReceive, asynchronousState); //Receive the remaining data
                            }
                            return;
                        }
                        ClientReceive(asynchronousState, bytes); //Announce receive
                        Array.Clear(asynchronousState.Buffer, 0, asynchronousState.Buffer.Length); //Clear the Buffer to begin receive more new data
                    }
                    if (socket.Connected) {
                        socket.BeginReceive(asynchronousState.Buffer, 0, asynchronousState.Buffer.Length, SocketFlags.None, HandleAsyncReceive, asynchronousState);
                        return;
                    }
                }
                DisposeSocket(asynchronousState);
Also do i need to edit the receive offset to avoid overwriting the buffer or the incoming information then will be the old + new bytes ?
Danial Eugen is offline  
Old 03/13/2014, 20:01   #12


 
KraHen's Avatar
 
elite*gold: 0
Join Date: Jul 2006
Posts: 2,216
Received Thanks: 794
This would only work if the packet is decrypted already. Also, if ClientReceive is null, you should still handle what`s going on, there`s a small chance you`d miss something with the code you posted above.

Disregarding these, yes, the general idea is correct. In a CO context, you`d decrypt the packet, check if the length is corresponding with the length you received in the packet header, and if not, you know that the next packet is still part of the current one.
KraHen is offline  
Old 03/14/2014, 03:12   #13
 
Danial Eugen's Avatar
 
elite*gold: 0
Join Date: Sep 2012
Posts: 171
Received Thanks: 68
Quote:
Originally Posted by KraHen View Post
This would only work if the packet is decrypted already. Also, if ClientReceive is null, you should still handle what`s going on, there`s a small chance you`d miss something with the code you posted above.

Disregarding these, yes, the general idea is correct. In a CO context, you`d decrypt the packet, check if the length is corresponding with the length you received in the packet header, and if not, you know that the next packet is still part of the current one.
I am just trying to get the whole idea infront of me so here is an updated version. Is this better/correct ?

Code:
                Socket socket = asynchronousState.Socket;
                int readLength = socket.EndReceive(ar);
                if (sizeof (PacketHeader) <= readLength) {
                    byte[] bytes = asynchronousState.Buffer.Take(readLength).ToArray();
                    ushort packetLength = BitConverter.ToUInt16(bytes, 0);
                    ushort packetType = BitConverter.ToUInt16(bytes, 2);
                    byte[] packetBody = bytes.Take(bytes.Length - 4).ToArray();
                    if (packetLength > readLength) {
                        //Fragmented Packet, receive more.
                        if (socket.Connected) {
                            socket.BeginReceive(asynchronousState.Buffer, 0, packetLength, SocketFlags.None, HandleAsyncReceive, asynchronousState);
                        }
                        return;
                    }
                    if (null != ClientReceive) {
                        //We have received the whole packet announce it.
                        ClientReceive(asynchronousState, new Packet
                        {
                            Header = new PacketHeader
                            {
                                Length = packetLength,
                                Type = packetType
                            },
                            Body = packetBody
                        });
                    }
                    Array.Clear(asynchronousState.Buffer, 0, asynchronousState.Buffer.Length); //Clear for new packet receiving.
                    if (socket.Connected) {
                        socket.BeginReceive(asynchronousState.Buffer, 0, asynchronousState.Buffer.Length, SocketFlags.None, HandleAsyncReceive, asynchronousState);
                        return;
                    }
                }
                DisposeSocket(asynchronousState); //Some condition didn't met so disconnect.
Do i need to set the receive index to the last write one or the next receive will receive both the old bytes as well as the new ones ?

socket.BeginReceive(asynchronousState.Buffer, 0, packetLength, SocketFlags.None, HandleAsyncReceive, asynchronousState) ?
Danial Eugen is offline  
Old 03/14/2014, 03:53   #14
 
elite*gold: 0
Join Date: May 2011
Posts: 648
Received Thanks: 413
yes
Y u k i is offline  
Old 03/14/2014, 17:34   #15
 
Danial Eugen's Avatar
 
elite*gold: 0
Join Date: Sep 2012
Posts: 171
Received Thanks: 68
Quote:
Originally Posted by Y u k i View Post
yes
yes what ?
Danial Eugen is offline  
Reply


Similar Threads Similar Threads
plz help me out with handling
09/01/2012 - Need for Speed World - 4 Replies
plz any1 send me a hack with obtion handling perfect DarkTitties idk but handling is no like the others i think no work rest work thx
Packet Handling Ways
01/17/2012 - CO2 Private Server - 5 Replies
well im interested in packet and i seen alot of examples of building packets so here is some examples Heres Example of Attack Packets : 1st Example public Attack(bool Create) { if (Create) { Buffer = new byte;
Socket Handling
11/03/2011 - CO2 Private Server - 3 Replies
Well i wanna know smthing about sockets ...i wanna handle about 500 Player (As an example) how to know the max number of player that my socket can handle without getting players in my server ??
Handling Packets
10/19/2011 - CO2 Private Server - 0 Replies
well iam learning Coding using C# Tutorials but i didnt find how to handle packets ..So any1 have tutorials or guides for that i'd be appreciate
[Question]New way of packet handling?
01/26/2011 - CO2 Private Server - 16 Replies
I have been thinking, and to me it seems that a lot of the packet handlers (especially LOTF) are pretty large. Would it take up more resources to do something more dynamic such as the following? This is just an example obviously. But the main concept is there. The void would be your PacketID, the Arg1 would be your data. And it simply calls the method immediately rather then going through a case? class Program { static void Main(string args) { string...



All times are GMT +1. The time now is 10:09.


Powered by vBulletin®
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2011, Crawlability, Inc.
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Support | Contact Us | FAQ | Advertising | Privacy Policy | Terms of Service | Abuse
Copyright ©2025 elitepvpers All Rights Reserved.