Register for your free account! | Forgot your password?

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

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

Advertisement



send/receive structs instead of ...

Discussion on send/receive structs instead of ... within the CO2 Programming forum part of the Conquer Online 2 category.

Reply
 
Old   #1
 
elite*gold: 0
Join Date: Sep 2012
Posts: 775
Received Thanks: 329
send/receive structs instead of ...

i was checking out chat applications in c++ and found this

Code:
int ServerThread(int ID)
{
	Buffer sbuffer;

	char* Recv = new char[256];
	ZeroMemory(Recv, 256);

	// In Send we will copy the content of the struct
	// and after this we will send "Send" to the client
	char* Send = new char[sizeof(Buffer)];
	ZeroMemory(Send, sizeof(Buffer));

	for(;; Sleep(10))
	{
		// Same here!
		if(recv(Connections[ID], Recv, 256, NULL))
		{
			sbuffer.ID = ID;
			memcpy(sbuffer.Message, Recv, 256);
			memcpy(Send, &sbuffer, sizeof(Buffer));

			for(int a = 0; a != ConCounter; a++)
			{
				if(Connections[a] == Connections[ID])
				{

				}
				else
				{
					send(Connections[a], Send, sizeof(Buffer), NULL);
				}
			}
			ZeroMemory(Recv, 256);
		}
	}

	return 0;
}
Code:
struct Buffer
{
	int ID;
	char Message[256];
};

int ClientThread()
{
	Buffer sbuffer;

	char buffer[sizeof(sbuffer)] = {0};

	for(;; Sleep(10))
	{
		// The server will send a struct to the client
		// containing message and ID
		// But send only accepts a char as buffer parameter
		// so here we need to recv a char buffer and then
		// we copy the content of this buffer to our struct
		if(recv(sConnect, buffer, sizeof(sbuffer), NULL))
		{
			memcpy(&sbuffer, buffer, sizeof(sbuffer));
			cout << "<Client " << sbuffer.ID << ":> " << sbuffer.Message <<endl;
		}
	}

	return 0;
}
server receives char array and use it to fill in "Buffer" struct with the client number to send it to the rest of clients (it obtain the client number as argument from a thread per client call)
what i found interesting was that

if(recv(sConnect, buffer, sizeof(sbuffer), NULL))
{
memcpy(&sbuffer, buffer, sizeof(sbuffer));
cout << "<Client " << sbuffer.ID << ":> " << sbuffer.Message <<endl;
}

how it could assign a char array (char pointer) to an struct of type Buffer
yeah both are void pointers but what happens behind the scene?
was it because the char array only contains 2 different types it was able to initialize that struct object members with them depending on the type ?

then what if i did the same but with 2 similar types ? ex. 2 ushorts at the same buffer , would it still be able to assign each ? depending on the order of the struct it got ?

i've heard something about that before (about how stupid the wrapper method people use and that there is a better way of getting this done)

sorry for asking too many questions but that saves me load of time to study something else instead of searching :P
go for it is offline  
Old 06/21/2013, 13:14   #2
 
Mr_PoP's Avatar
 
elite*gold: 0
Join Date: Apr 2008
Posts: 759
Received Thanks: 285
you got it wrong! , the recvedbuffer actually is a packet structure(int,char[256]), as the Buffer, so you have (int32)(00 00 00 00) and (byte)(00 * 256), by saying copy the memory of this recvedbuffer to Buffer , it will take the 1st 4bytes from the recvedbuffer copy it to the 1st 4bytes in Buffer which is (int), and will copy the left 256bytes from recvedbuffer to the Buffer which is (char[256]).

that's how TQ build it's packets so they have:

structure SpwanPacket{
ushort length;
ushort type;
uint enityId;
uint messh;
etc;
};

and they copy it to the memory that's why if they add a new value inside the structure the whole packet changes !
Mr_PoP is offline  
Thanks
1 User
Old 06/21/2013, 13:22   #3
 
InfamousNoone's Avatar
 
elite*gold: 20
Join Date: Jan 2008
Posts: 2,012
Received Thanks: 2,885
and then u run into 2 lovely issues called
1. dynamic packets
2. packing alignment
InfamousNoone is offline  
Thanks
2 Users
Old 06/21/2013, 13:32   #4
 
elite*gold: 0
Join Date: Mar 2013
Posts: 118
Received Thanks: 95
Quote:
Originally Posted by InfamousNoone View Post
and then u run into 2 lovely issues called
1. dynamic packets
2. packing alignment
3. Fragmentation
Smaehtin is offline  
Thanks
1 User
Old 06/21/2013, 15:10   #5


 
CptSky's Avatar
 
elite*gold: 0
Join Date: Jan 2008
Posts: 1,443
Received Thanks: 1,175
Quote:
Originally Posted by InfamousNoone View Post
and then u run into 2 lovely issues called
1. dynamic packets
2. packing alignment
Well, not big problems...

Code:
    #pragma pack(1)
    typedef struct
    {
        Msg::Header Header;
        uint32_t Color; // ARGB code
        int16_t Channel;
        int16_t Style;
        int32_t Timestamp;
        uint8_t Buf[1];
    }MsgInfo;
    #pragma pack(pop)
CptSky is offline  
Thanks
2 Users
Old 06/21/2013, 16:53   #6
 
elite*gold: 0
Join Date: Sep 2012
Posts: 775
Received Thanks: 329
about Fragmentation it's not a big deal to me as i can assign after i receive the complete packet so there is nothing to worry about (as i bet tq client should be doing the same)

about dynamic packet and packet alignment
i've seen a thread you made about it
but i guess there is away around to define a struct with a variable size
didn't honestly understand the example cptsky said

but is there a better way of getting that done ?
go for it is offline  
Old 06/21/2013, 17:33   #7
 
Mr_PoP's Avatar
 
elite*gold: 0
Join Date: Apr 2008
Posts: 759
Received Thanks: 285
Quote:
Originally Posted by CptSky View Post
Well, not big problems...

Code:
    #pragma pack(1)
    typedef struct
    {
        Msg::Header Header;
        uint32_t Color; // ARGB code
        int16_t Channel;
        int16_t Style;
        int32_t Timestamp;
        uint8_t Buf[1];
    }MsgInfo;
    #pragma pack(pop)
it's a prob! consider the ChatPacket , you don't know what is the msg length is going to be!, because it's dynamic ,therefore you going to hack the structure by pulling out the msg (resize/copy to) it then send the structure, where when we pass arguments to the constructor we will have a better way of controlling it! don't you agree?
Mr_PoP is offline  
Thanks
1 User
Old 06/21/2013, 18:35   #8


 
CptSky's Avatar
 
elite*gold: 0
Join Date: Jan 2008
Posts: 1,443
Received Thanks: 1,175
Quote:
Originally Posted by Mr_PoP View Post
it's a prob! consider the ChatPacket , you don't know what is the msg length is going to be!, because it's dynamic ,therefore you going to hack the structure by pulling out the msg (resize/copy to) it then send the structure, where when we pass arguments to the constructor we will have a better way of controlling it! don't you agree?
Well, the struture is internal to the MsgTalk class. So, it's only a cast over a byte buffer to put values directly in memory without handling any offset, etc. When I construct the object, the internal buffer is allocated with the real size in mind, so the MsgInfo struct is less than the internal buffer. By using a string packer on the last byte, you can easily write any dynamic packet.

You can't only have a simple structure, but if it's neasted inside a class, it's easier than managing the offset yourself, etc.

Code:
MsgTalk :: MsgTalk(const char* aSpeaker, const char* aHearer, const char* aWords,
                   Channel aChannel, uint32_t aColor)
    : Msg(sizeof(MsgInfo) +
          (aSpeaker != nullptr ? strlen(aSpeaker) : 0)  + 1 +
          (aHearer != nullptr ? strlen(aHearer) : 0)  + 1 +
          /* (aEmotion != nullptr ? strlen(aEmotion) : 0) */ + 1 +
          (aWords != nullptr ? strlen(aWords) : 0) + 1)
{
    mInfo = (MsgInfo*)mBuf;
    create(aSpeaker, aHearer, "", aWords, aChannel, aColor); // HACK !
}

MsgTalk :: MsgTalk(uint8_t** aBuf, size_t aLen)
    : Msg(aBuf, aLen)
{
    ASSERT(aLen >= sizeof(MsgInfo));

    mInfo = (MsgInfo*)mBuf;
    #if BYTE_ORDER == BIG_ENDIAN
    swap(mBuf);
    #endif
}
CptSky is offline  
Thanks
1 User
Old 06/21/2013, 19:00   #9
 
Mr_PoP's Avatar
 
elite*gold: 0
Join Date: Apr 2008
Posts: 759
Received Thanks: 285
Quote:
Originally Posted by CptSky View Post
Well, the struture is internal to the MsgTalk class. So, it's only a cast over a byte buffer to put values directly in memory without handling any offset, etc. When I construct the object, the internal buffer is allocated with the real size in mind, so the MsgInfo struct is less than the internal buffer. By using a string packer on the last byte, you can easily write any dynamic packet.

You can't only have a simple structure, but if it's neasted inside a class, it's easier than managing the offset yourself, etc.[..]
I always wanted to do that in C# in safe way, without allowing unsafe code , but I couldn't lol, I agree it's better in away YOU DON'T CARE where is the offset it's handling it's self making it easier for you to deal with packets.
Mr_PoP is offline  
Thanks
1 User
Reply


Similar Threads Similar Threads
Structs
09/11/2011 - WarRock - 0 Replies
hey epvp und zwar suche ich jemanden der mir es beibringen kann Structs zu Updaten oder mir die aktuellen structs geben kann :) were echt toll wenn mir das jemand beibringen kann :) added mich einfach skype: wrk1ng007 Leider kan ich euch dafür ncihts geben ;(
Suche aktuelle structs
09/07/2011 - WarRock - 3 Replies
Hallo und zwar wollte ich fragen ob jemand die aktuellen structs für mich hat :) danke im vorraus :D
List of Send/Receive Packtet Editors?
05/22/2009 - General Coding - 2 Replies
Anyone can give me list of Packet editors you can send and receive? Besides WPE pro
[Request] Packet Structs
10/14/2008 - CO2 Private Server - 9 Replies
So, has anyone structured the packets for patch 5017? If so, any change you could either post them here or PM them to me? I'm looking for complete structures so I don't need the actual code.



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


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.