Jump to content
  • Advertisement
Sign in to follow this  
X5-Programmer

Design / Send-Recv

This topic is 4944 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi there, I have wondering how to do the best send, recv structure for my game. I have an structure to use all the time when I send/recv data.. let me explain, this is the structure.
struct sbtsWData
{
	short length, pointer;
	short opcode;
	short packetSize;
	char  *data;

	/// Constructor
	sbtsWData( ):data( 0 ), length( 0 ), opcode( 0 ), pointer( 0 ) { }

	 // Destructor
	~sbtsWData( ) {
		clear( );
	}

	void Initialise( unsigned short newLength, unsigned short newOpcode ) {
		
		packetSize = newLength;
		setLength( newLength );
		opcode = newOpcode;
	}	

	void clear( ) {
    if( data )
      delete [] data;
		data = 0;
		opcode = 0;
	}

	short GetPacketSize() { return packetSize; }

	void setLength( unsigned short newlength )
	{
	    if( (newlength > length) | (data==0) ) {
		clear( );
		data = new char[newlength];
		}else 
		{		
			pointer = 0; opcode = 0;
		}
		length=newlength;
	}

	template < class type > inline sbtsWData & operator<<( const type &newData  ) {
    writeData( newData );
    return *this;
	}
	  template < class type > inline sbtsWData & operator>>( type &newData ) {
		readData( newData );
		return *this;
	}
  
	inline sbtsWData & operator<<( const char * newData ) {
		writeData( newData );
		return *this;
	}
	inline sbtsWData & operator>>( char * newData ) {
		readData( newData );
		return *this;
	}
  
	inline short & writeData( const void * newData, const short datalength ) {
		return pointer = writeDataAt( pointer, newData, datalength );
	}
	inline short & readData( void * newData, const short datalength ) {
		return pointer = readDataAt( pointer, newData, datalength );
	}

	template < class type > inline short & writeData( const type &newData ) {
		return pointer = writeDataAt( pointer, newData );
	}
	template < class type > inline short & readData( type &newData ) {
		return pointer = readDataAt( pointer, newData );
	}

	inline short & writeData( const char * newData ) {
		return pointer = writeDataAt( pointer, newData );
	}
	inline short & readData( char * newData ) {
		return pointer = readDataAt( pointer, newData );
	}

	inline short writeDataAt( const short offset, const char * newData ) {
		short dlen = strlen( newData ) + 1;
		WPAssert( offset + dlen <= length );
		memcpy( data + offset, newData, dlen );
		return offset + dlen;
	}
	inline short readDataAt( const short offset, char * newData ) {
		short dlen = strlen( (char *)data + offset ) + 1; 
		WPAssert( offset + dlen <= length );
		memcpy( newData, data + offset, dlen );
		return offset + dlen;
	}

	template < class type > inline short writeDataAt( const short offset, const type &newData ) {
		WPAssert( offset + sizeof( type ) <= length );
		memcpy( data + offset, &newData, sizeof( type ) );
		return offset + sizeof( type );
	}
	template < class type > inline short readDataAt( const short offset, type &newData ) const {
		WPAssert( offset + sizeof( type ) <= length );
		memcpy( &newData, data + offset, sizeof( type ) );
		return offset + sizeof( type );
	}

	inline short writeDataAt( const short offset, const std::string &newData ) {
		short dlen = newData.length( ) + 1; // trailing zero is included
		WPAssert( offset + dlen <= length );
		memcpy( data + offset, newData.c_str( ), dlen );
		return offset + dlen;
	}

	inline short readDataAt( const short offset, std::string &newData ) {
		newData = (char *) data + offset;
		short dlen = newData.length( ) + 1;
		WPAssert( offset + dlen <= length );
		return offset + dlen;
	}
  
	inline short writeDataAt( const short offset, const void * newData, const short datalength ) {
		WPAssert( offset + datalength <= length );
		memcpy( data + offset, newData, datalength );
		return offset + datalength;
	}

	inline short readDataAt( const short offset, void * newData, const short datalength ) const {
		WPAssert( offset + datalength <= length );
		memcpy( newData, data + offset, datalength );
		return offset + datalength;
	}
};

Well this is how I use it. to build a packet to send a simple string I do this. sbtsWData data; char text[32]; strcpy(text, "test"); short lenght = strlen(text); short size = sizeof(char)+lenght; data.clear(); data.Initialise(size, CMSG_1); data.writeData( text ); m_connection->Send((char*)&data, sizeof(sbtsWData)); and it works just fine to send the packet, but on the recv side I got problem, I recv it like this. sbtsWData *data; recv(mySocket, (char*)&data, sizeof(sbtsWData)); dont think thats right way to do this. anyway, then to use the recv data. char text[32]; if(data->opcode == CMSG_1) data->SetLenght( data->lenght ); *data >> text; printf(text); data->clear(); and I get error, the *data >> text; do the error, can't see whats wrong : but if I do this I dont get any errors. if(data->opcode == CMSG_1) { printf(data->lenght); } it prints out the lenght of the packet just fine so it have recv the data, or not all of it? bahh, hope anyone know what I mean, and if you know a bettere way to send/recv plz tell :) thanks.

Share this post


Link to post
Share on other sites
Advertisement
I'm not sure if this is your problem, but it should definitely be fixed.

sbtsWData *data;
recv(mySocket, (char*)&data, sizeof(sbtsWData));

You declare data as a pointer, but when passing it to the recv function, you use &data, which creates a pointer to a pointer. What you should probably do is declare it like this instead.

sbtsWData data;

Share this post


Link to post
Share on other sites
Yea, I saw that, but I think my problem is how to recv all the data.

like this,

char *recvq;

int recvqmax;
int templen;

templen = recv(mSocket, recvq + recvqlen, recvqmax + recvqlen, 0);

recvqlen += templen;

or something :S donw know.

[Edited by - X5-Programmer on January 5, 2005 7:31:29 AM]

Share this post


Link to post
Share on other sites
When you take the address of "data", the struct, you only get the struct, not the data pointed at by its "data" pointer. When writing, you need to either use scatter/gather (a la writev()), or you need to create a single byte buffer that contains your entire packet (by copying), and then sending that.

In my packet class, I say that I won't ever send a packet greater than 1500 bytes. Then, I make the actual data buffer be a member of the packet class (preceeded by length, read pointer, etc).

Share this post


Link to post
Share on other sites
Quote:
Original post by hplus0603
When you take the address of "data", the struct, you only get the struct, not the data pointed at by its "data" pointer. When writing, you need to either use scatter/gather (a la writev()), or you need to create a single byte buffer that contains your entire packet (by copying), and then sending that.

In my packet class, I say that I won't ever send a packet greater than 1500 bytes. Then, I make the actual data buffer be a member of the packet class (preceeded by length, read pointer, etc).



i do it a little bit different

my network engine collects outgoing messages sorts them by type e.g. UDP(reliable/unreliable) or TCP do some bit compressions

then i get the messages by priority and at it to the packet

once this is done i check if its more then 200 bytes if so i perform a huffman compression which usually reduces size by 12-30%

and then i send

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!