Archived

This topic is now archived and is closed to further replies.

bmsfx

Help, im cant get this....

Recommended Posts

okay, here is the deal. my server sends out a auth packet on connection, should be like this size [xx xx] id [xx] data [xx xx xx xx xx xx] and so on.... here is the problem... i send a packet, size 10 [0A 00] with opcode 0x29 [29] and data "1234567" thats a total of 10, but when i send it out, i get this from a sniffer (i guess it tells me something is wrong, i dont receive the 1234567), since my packet get to target looking like this: [04 00] [29] [some wierd stuff] size 10. should have been [0A 00] [29] [1234567] size 10. hex A = 10 hex 4 = 4 so i guess its the packet size it sends wrong, therefor it dont send the data, however if you look at the code, i can tell you, the 3rd time it sends (Server send->receive->send again), it sends both the Mini1 "hello" and the "1234567". can anyone see the error????
struct UpdaterPacket
{
	int16 size; /* sends xx xx */
	int8 opcode; /* sends xx, size + opcode = +6 to send */
	char data[65536]; /* data */
};

struct AuthPacket
{
	char *Authdata; /* put data in here to send */
};

bool EchoIncomingPackets(SOCKET sd)
{
	int currentSizeReceived;
	int bytesIn;
	int bytesOut;
	currentSizeReceived = 0;

	struct UpdaterPacket p;
	struct AuthPacket d;
	
	p.size=sizeof(AuthPacket);
	d.Authdata="1234567";
	p.opcode=0x29;

	memcpy(&p.data,&d,p.size);

	bytesOut = send(sd, (char*)&p, p.size+6, 0);
	if (bytesOut > 0)
	{
	char buffer[65000];
	bytesIn = recv(sd, buffer, 200, 0);
	}
	if (bytesIn > 0)
	{
		int nSentBytes = 0;
            while (nSentBytes < bytesIn)
			{

			char *Mini1;
			Mini1 = "hello";
			int nTemp = send(sd, Mini1, 14+6, 0);

			if (nTemp > 0)
			{
				nSentBytes += nTemp;
			}
            else if (nTemp == SOCKET_ERROR)
			{
				return false;
			}
		}
	}

return true;
}
Thanks. btw: i know the code looks wierd, but its just to test some stuff. [edited by - Bmsfx on March 22, 2004 11:24:37 AM]

Share this post


Link to post
Share on other sites
Hello bmsfx,

What is the protocol you're using? UDP or TCP?

Next the code you have is off a bit.

p.size=sizeof(AuthPacket);

this give you a size of 4 bytes since this struct has only a pointer member.

You then asigned this pointer to the data you want to send.

So now you have your p struct size set to 4 bytes.
p.data has in it the first 4 byte of your data "1234" by way of the memcpy.

then your sending out your struct of only p.size + 6 bytes which is 10 bytes. which is 3 bytes more then you actual initialize.
you set the size 2 btyes there, op 1 byte, and copy 4 bytes into data.

Then your sending out the struct but is the struct byte packed?
ie has no padding added for alignment.

Here is what you need the do.


struct UpdaterPacket
{
int16 size; /* sends xx xx */
int8 opcode; /* sends xx, size + opcode = +6 to send */
char data[65536]; /* data */
};

struct AuthPacket
{
char *Authdata; /* put data in here to send */
};

bool EchoIncomingPackets(SOCKET sd)
{
int currentSizeReceived;
int bytesIn;
int bytesOut;
currentSizeReceived = 0;

struct UpdaterPacket p;
struct AuthPacket d;

d.Authdata="1234567";
// sizeof(AuthPacket) is only 4 becuase it only has a pointer memeber

p.size=strlen(d.Authdata); // sizeof(AuthPacket);

p.opcode=0x29;

memcpy(&p.data,d.Authdata,p.size); // now have "1234567" in p.data correctly


//bytesOut = send(sd, (char*)&p, p.size+6, 0);

// need to flatten (remove padding)

char buf[sizeof(p.size)+sizeof(p.opcode)+sizeof(p.data)];
char* buf_ptr= buf; // done so we can mover buf_ptr to were we need to memcpy

memcpy(buf_ptr,(char*)&p.size,sizeof(p.size));
buf_ptr+=sizeof(p.size);
memcpy(buf_ptr,&p.opcode,sizeof(p.opcode));
buf_ptr+=sizeof(p.opcode);
memcpy(buf_ptr,p.data,p.size);
// now you have a buf with size, opcode and data in it no padding and ready to send

bytesOut = send(sd, buf, p.size+6, 0);
// This should fix your sending problem but I don't understand what your trying to do after this

if (bytesOut > 0)
{
char buffer[65000];
bytesIn = recv(sd, buffer, 200, 0);
}
if (bytesIn > 0)
{
int nSentBytes = 0;
while (nSentBytes < bytesIn)
{

char *Mini1;
Mini1 = "hello";
// this make no since your send more bytes then Mini1 is pointing to 14+6 is more then 5 that "hello" is.

int nTemp = send(sd, Mini1, 14+6, 0);

if (nTemp > 0)
{
nSentBytes += nTemp;
}
else if (nTemp == SOCKET_ERROR)
{
return false;
}
}
}

return true;
}


The main point is you can't asign pointers and send the structure.
you have to send what the pointer points to.
Also most compiler add padding to structurs unless told not to.
I belive you don't have padding but it is always smart to make sure you flatten the structure so as it does not need to worry about the padding.

Lord Bart

Edited:
Oh this doesn't assume any byte order as Big or little Endian.
If this could go cross platform (between Big and little Endian systems) you might want to make it Network ordered (ie Big Endian).

Lord Bart

[edited by - lord bart on March 22, 2004 3:00:13 PM]

[edited by - lord bart on March 22, 2004 3:10:13 PM]

Share this post


Link to post
Share on other sites
// this make no since your send more bytes then Mini1 is pointing to 14+6 is more then 5 that "hello" is.

i know, its my mistake, i just did a quick number, didnt change it since i had probs with the first packet, changed it now tho

btw its TCP im trying to do

i changed the send a bit, since it was sending 13 bytes instead of 10 to

bytesOut = send(sd, buf, p.size+3, 0);

but on the client edge, i receive a size of 07 00 (that is correct, however i need the complete packet size (that is 0A 00) for 10 bytes, it doesnt count in the 3 bytes (size+opcode) in the packet size header.

but thats not a problem ,ill fix that, thanks for the reply, gave me a few things to work with and consider on the data transmissions...

quick, fast and professional help = gamedev

thanks again.



[edited by - Bmsfx on March 22, 2004 3:53:53 PM]

Share this post


Link to post
Share on other sites
If it was UDP you could just send the packet (which has to be less then 65535-(udp header size)) and then just read the UDP packet at reciver, knowing that the packet couldn't be bigger then 65535-udp header size.

Ok TCP,

This is what I would do.
Send a Int32 Network order size of message to follow.

Then send the buffer that is your message.

This way recvier can read a Int32 Network order and know it needs to read a buffer of the size it just read.

But for now just send Int32 size for message to follow.


int size_to_send;
bool EchoIncomingPackets(SOCKET sd)
{
int currentSizeReceived;
int bytesIn;
int bytesOut;
currentSizeReceived = 0;

struct UpdaterPacket p;
struct AuthPacket d;

d.Authdata="1234567";
// sizeof(AuthPacket) is only 4 becuase it only has a pointer memeber

p.size=strlen(d.Authdata); // sizeof(AuthPacket);

p.opcode=0x29;

memcpy(&p.data,d.Authdata,p.size); // now have "1234567" in p.data correctly


//bytesOut = send(sd, (char*)&p, p.size+6, 0);

// need to flatten (remove padding)

char buf[sizeof(p.size)+sizeof(p.opcode)+sizeof(p.data)];
char* buf_ptr= buf; // done so we can mover buf_ptr to were we need to memcpy

memcpy(buf_ptr,(char*)&p.size,sizeof(p.size));
buf_ptr+=sizeof(p.size);
memcpy(buf_ptr,&p.opcode,sizeof(p.opcode));
buf_ptr+=sizeof(p.opcode);
memcpy(buf_ptr,p.data,p.size);
// now you have a buf with size, opcode and data in it no padding and ready to send

// TCP on each send is two sends one size of buffer then buffer send

size_to_send = p.size + 3; // 3, 2 for size and 1 for opcode p.size has size of data already.

bytesOut = send(sd, (char*)&size_to_send, sizeof(size_to_send), 0);
if(byteOut!=sizeof(size_to_send))
{
// we didn't send right num of bytes

return false;
}
// now send buf

bytesOut = send(sd, buf, size_to_send, 0);
// This should fix your sending problem but I don't understand what your trying to do after this

if (bytesOut > 0)
{
char buffer[65000];
bytesIn = recv(sd, buffer, 200, 0);
}
if (bytesIn > 0)
{
int nSentBytes = 0;
while (nSentBytes < bytesIn)
{

char *Mini1;
Mini1 = "hello";
// this make no since your send more bytes then Mini1 is pointing to 14+6 is more then 5 that "hello" is.

int nTemp = send(sd, Mini1, 14+6, 0);

if (nTemp > 0)
{
nSentBytes += nTemp;
}
else if (nTemp == SOCKET_ERROR)
{
return false;
}
}
}

return true;
}



Now of recivering side you do a read(sd,(char*) &size_to_read, sizeof(size_to_read));
then have a buf of correct size to read.
read(sd, buf, size_to_read);

Then memcpy values into your UpdaterPacket struct.

I point is with TCP you if not going to send the same size packet for each send, then you need to send size you will send and then send the buffer.

Lord Bart

[edited by - lord bart on March 22, 2004 5:00:32 PM]

Share this post


Link to post
Share on other sites
i did no.2 you said, i still only receive a 07 00 not a 0A 00

it only calculates the size of the data to send me, when it really needs to calculate the date + size + opcode

i tryed to do this to calculate the size

char fakesizeadd;
fakesizeadd="ab"; // add +2 to size header
p.size=strlen(d.Authdata)+sizeof(p.opcode)+strlen(fakesizeadd);

then my header really is the size 0A 00 BUT it add's 3 empty bytes at end..

eg: [0A 00] [29] [31 32 33 34 35 36 37] [00 00 00]
i know why ofcourse, thats because i send 10 bytes instead of 7 so it ofcourse sends 10.., but you know what im trying to do ?

i need to make a packet that looks like this:
[0A 00] [29] [31 32 33 34 35 36 37]

server sends this packet
[total packet size, including size itself] + [opcode] + [data]

client gets it it (it is predefined to know packed lenght is +2]
[0A 00] [29] [31 32 33 34 35 36 37]

the client then do all the packet encoding, knowing the data size = the size header -2 bytes for the header size -1 byte for the opcode.

that means i can pull the packet apart on the client size like this:

packet in = [0A 00] [29] [31 32 33 34 35 36 37]

the size header is always 2 bytes so:

[0A 00] = 2 bytes = total packet size
[29] = 1 byte = opcode
[------data-----] = packetsize-2(to get data size)-opcodesize = datasize.

that would do 10-2-1 = 7 for datasize.

its hard to explain...

[edited by - Bmsfx on March 23, 2004 7:03:46 AM]

Share this post


Link to post
Share on other sites
Ok Now I see what you want.

You want only to send the packet with size of packet in the packet.
So you want the size data memeber to be 3+len of data.
Then you want to send this TCP and have the other side get this packet.
This can be done following ways.
One send call for transmit send(sd, (char*)&p, p.size,0);
two recv calls one to just read size data member.
the next to read the rest of the packet.
recv(sd, (char*)&p.size, sizeof(p.size), 0);
then then recv(sd, (char*)&p.opcode,p.size-2,0);
or
two send and two recv calls.
send(sd, (char*)&p, sizeof(p.size),0);
send(sd, (char*)&p.opcode, p.size-2,0);
then om revc side
recv(sd, (char*)&p.size, sizeof(p.size), 0);
recv(sd, (char*)&p.opcode,p.size-2,0);

This is the only way to go if your going to send variable length data in your packet.

Or you could always send the entire packet always sizeof(p) and not have to worry about two reads. But that could waste alot of bandwith.

TCP sends no info about size of data coming since it is a stream protocol. Therefore you sould send the size first then the actual message, or send predifined packet size.

I would still create a flatten byte buffer to send instead of the actual structure if this could be sent to different platforms or programs.

Lord Bart

[edited by - lord bart on March 23, 2004 8:44:10 AM]

Share this post


Link to post
Share on other sites