🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

sending text messages

Started by
13 comments, last by djsteffey 23 years, 5 months ago
how could i send messages of varying size like i want to be able to send text messages in my game obvously the text messages can be of varying size and will be larger then the normal position packets sent is there a way for me to send a text message and the receiver know it is a text message and how big it is i was thinking something like this send a normal packet (the same size as the normal position packets) but have it empty except for the command will be TEXT_MESSAGE and one of the variables will contain how big the text message is then immediately send a char buffer that contains the text and nothing else then on the receiving side.......when i detect a normal packet that has the TEXT_MESSAGE command, i know the next incoming information will be a text message with the length indicated in the previous packet. these seems like the hard way to do it......is there an easier way ? "Now go away or I shall taunt you a second time" - Monty Python and the Holy Grail themGames Productions
Advertisement
I''d do it this way:

send a normal packet with the TEXT_MESSAGE command, right after that the charakter stream.. then abort it as soon as the ''\0'' charakter appears.. also, you could somehow compress the message, cause a lot of charakters won''t be used..

just my thoughts,
cya,
Phil

Visit Rarebyte!
and no!, there are NO kangaroos in Austria (I got this questions a few times over in the states
Visit Rarebyte! and no!, there are NO kangaroos in Austria (I got this question a few times over in the states ;) )
this is how i do it:


// define maximum text message length in characters
#define MAXTEXTLEN 100

// message types
enum {
MSG_LOGINREQUEST = 1,
MSG_LOGINREPLY,
MSG_TEXT,
MSG_CONNECT,
MSG_DISCONNECT
};

// text message structure
struct MsgText {
int m_Type; // type of message, MSG_TEXT for text
char m_Buffer[MAXTEXTLEN]; // buffer for text message
};

// create packet and send
MsgText msg;
ZeroMemory(&msg, sizeof(MsgText));
msg.m_Type = MSG_TEXT;
strcpy(msg.m_Buffer, "This is a text message from me.");
send((void *)&msg);
---===xxxx===---
----THE END----
---===xxxx===---
If you are using UDP, you can ask wsa for the packet size. The packet structure should have everthing a constant size except the payload (which would contain the text msg in the case of a chat packet).

If you''re using TCP the first thing sent with every packet should be (must be!) the amount of data that''s coming.

  //tcp exampleenum PacketType	{	PT_EMPTY        = 0x0000,	PT_CHAT         = 0x0001,	PT_LOGIN        = 0x0002,	PT_PING         = 0x0003,	PT_PONG         = 0x0004,	PT_PLAYER       = 0x0005,	PT_FORCEDWORD   = 0xFFFFFFFF	};class CPacket	{	public:		CPacket();		~CPacket();		//friend class CRecvSocket;		//friend class CNetworkClient;		void Chat(const CString&);		//void Player(const CPlayer&);		void Player(const CPlayer&);		void Pack(const void*, long);				void Serialize(CArchive& ar);		friend CArchive& operator<<(CArchive& arc, const CPacket& packet);		friend CArchive& operator>>(CArchive& arc, CPacket& packet);				const PacketType& GetPacketType()			{			return(packettype);			}	//protected:		DWORD GenerateSerial(DWORD);		DWORD GenerateECC();	//private:		long length;		PacketType packettype;		DWORD serialnum;		DWORD ecc;		char* data;			};//the sendCArchive& operator<<(CArchive& arc, const CPacket& packet)	{	if (arc.IsStoring())		{		arc << packet.length;		arc << (long)packet.packettype;		arc << packet.serialnum;		int n = packet.length - sizeof(CPacket) + sizeof(packet.data);		for(int i=0;i<n;i++)			arc << packet.data<i>;		arc << packet.ecc;		}	return(arc);	}//the receiveCArchive& operator >>(CArchive& arc, CPacket& packet)	{	if (!arc.IsStoring())		{		long pt;		arc >> packet.length;		arc >> pt; packet.packettype = (PacketType) pt;		arc >> packet.serialnum;		if(packet.data)			delete[] packet.data;		int n = packet.length - sizeof(CPacket) + sizeof(packet.data);		packet.data = new char[n+1];		packet.data[n]=0;		for(int i=0;i<n;i++)			{			int b = arc.IsBufferEmpty();			arc >> packet.data[i];			}		arc >> packet.ecc;		DWORD cs = packet.GenerateECC();		if(cs!=packet.ecc)			{			char* breakhere =0;			*breakhere = *breakhere; //something went horribly wrong!			}		}	return arc;	}  
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
I know this was a while back but i just wanted to post the answer to my question here in case anyone else is wondering how.
Lets say each packet of data for my game is 20 bytes. And lets say I want to send a text message 70 characters long. Well the first byte of the data packet is always what type of info it contains.......like position, fired bullet, new player, etc. I just added a new type called TEXT_MESSAGE. So if the message is 70 characters long.....then I will send 4 consecutive packets with the type of TEXT_MESSAGE. Then I will reassemble them on the other side. You do have to account for them getting out of order and the such which I do. But you can figure that out on your own.


"Now go away or I shall taunt you a second time"
- Monty Python and the Holy Grail
We are creating a Multi-player space strategy/shoot-em-up/RPG game.
Development is well under way and we do have a playable demo.
Always looking for help.
Digital Euphoria Soft

Using DPlay all you have to do is have to do is specify exactly how big the message is. My packet struct is simply

struct message
{
unsigned char type;
unsigned char msg[65536];
}

when I send I set sizeof to how many bytes I actually want to send. My struct is 64k but I can send 1 byte if I want. When it reaches it''s destination the type value tells the client or server how to interpret the message.

Course I''ve noticed most dispise Dplay for whatever reason on this list. I''m sure Winsock can utilize the same trick though.

Ben












how does the receiver know how big the packet is ? Do you have a specified size for the text messages. Like all text messages are 60 bytes ? Because the receiver needs to know how much data is coming in dont they ? And how do you get just the type info ? Do you read just the first byte of the packet see what type it is...then read the rest into the appropriate place? Or do you read the whole thing into a buffer ? I am pretty sure on the second question so my main question is how does the receiver know how much data to receive ?


"Now go away or I shall taunt you a second time"
- Monty Python and the Holy Grail
We are creating a Multi-player space strategy/shoot-em-up/RPG game.
Development is well under way and we do have a playable demo.
Always looking for help.
Digital Euphoria Soft

type tells the server or client if it''s a text message or something else. The same struct is also used to send position updates and everything else.

message_struct
{
unsigned char type, data[65536];
}


say the text type is 5

so you''d go

message.type=5
message.data[0]=3
message.data[1]=''H'';
message.data[2]=''I'';
message.data[3]=''!'';

since the data array is 65536 characters you have to adjust the send routine accordingly

g_pDP->Send( g_LocalPlayerDPID, PlayerSendToID, DPSEND_GUARANTEED, &message, sizeof(message_struct)-65536+4);

By subtracting 65536 we tell the send command we are only sending the bytes in variables defined prior to the data array.

It''s + 4 since there are 4 values you need to get sent within the data array.

The server does automatically retrieve the size of messages sent to it. In this case it would be 5 since the type is one byte.

You''ll just need a routine at the destination end to check what type the message is and how to read it.

It has to be chars or unsigned chars for the struct to work. If you change it to say shorts then you would double everything. It''s easier just to break everything down to chars prior to sending. If you have decimals you''ll have to get them to integers and then break them up. Then do the reverse on the recieving end.

Once you get that going you can use it with everything. It''s basically a binary file.

Ben

so the receiver automatically knows how much data is sent to it so you dont have to specify how much data to read ?
I am almost positive you have to do this in Winsock. But you are using DirectPlay so. Anyhow......I do have mine working fine and dandy and packets are small so I am happy with the way I have done it. I was just curious to your method and plus this lets other people reading this might figure out how to do some stuff.


"Now go away or I shall taunt you a second time"
- Monty Python and the Holy Grail
We are creating a Multi-player space strategy/shoot-em-up/RPG game.
Development is well under way and we do have a playable demo.
Always looking for help.
Digital Euphoria Soft

Part of the UDP packet header is how big the packet is. The UDP packet header is a fixed size, so you always know how much data was sent (so long as you stay under 1500, or whatever odd value the MTU happens to be).

Typically the data actually sent has a header itself that describes the rest of the data attached. ie whether is a chat packet, position update, login request, attack, etc...
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara

This topic is closed to new replies.

Advertisement