Screenshot.

Hello, I have a problem already for like a week and I seriously can't get out of it. Take a look at the screen shot.

The server sends a packet to the client to spawn an NPC. If you look to the top commandline-window, the client does recv the packet good and spawns the NPC, at first with the arguments specified. But after that, and I don't know how it comes, the NPC gets a name as PC:100 and the text he says is a "!" if you can see it.
What am I doing wrong?
Here is the code when im parsing the packets.

while(1) {
		packet = Client->Recv();
		LoadTime = GetTickCount();

		command = strtok(packet, ":");

		for(int i = 0; i < 10; i++)
			args[i] = strtok(NULL, ",");


		switch(Commands[command]) 
		{
		case c_Disconnected:
			MessageBox(MainWnd, "Disconnected from the server!", "Error:", 0);
			exit(0);
			break;

		case c_Join: {
			float endtime = (float)(GetTickCount()-LoadTime)/1000;
			cout << "Got packet in " << endtime << " seconds\n" << endl;

			cout << "Received Join\n";
			GUI::AddMessage(FLAG_SYSTEM, "Connection with the server established.");
			cout << "Name was \"" << Player1->GetName() << "\" and is now \"" << Player1->SetName(args[0]) << "\".\n";	
					 }
			break;
			
		case c_Mofd:
			if(!args[0]) {
				Client->Send("NotValid:Mofd,No message of the day specified!");
				break; // If there are some arguments empty, just exit to prevent crashes.
			}
			GUI::AddMessage("Message Of The Day", "%s", args[0]);
			break;

		case c_SpawnNPC:
			if(!args[0] || !args[1] || !args[2] || !args[3] || !args[4] || !args[5]) {
				Client->Send("NotValid:SpawnNPC,%s!", (args[0] == 0) ? "No name specified" : 
													  (args[1] == 0) ? "No type specified" :
													  (args[2] == 0) ? "No X position specified" :
													  (args[3] == 0) ? "No Y position specified" :
													  (args[4] == 0) ? "No text specified" :
													  (args[5] == 0) ? "No HP specified" : "Unknown error");
				break; // If there are some arguments empty, just exit to prevent crashes.
			}

			temp = Client->SpawnNPC(DirectX, args[0], (TYPES)atoi(args[1]), atof(args[2]), atof(args[3]), args[4], atoi(args[5]));
			Client->Send("Succes:Succesfully spawned NPC %s saying %s", temp->GetName(), temp->GetText());

			cout << "SpawnNPC\n{\n";
			for(int i = 0; i < 6; i++)
				cout << "\t" << args[i] << endl;
			cout << "}\n";
			break;

		default:
			cout << command << " is not a valid command.\n";
			break;
		}

		for(int i = 0; i < 10; i++)
			args[i] = 0;
	}
}

Excuse me for the length.

If you happen to know what i'm doing wrong, please tell me.

Thanks alot!

Recommended Answers

All 12 Replies

Bump
Does no one know the answer?

> packet = Client->Recv();
Can you post the code for Recv() and Send()?

Oh sure, here you go.

char* CLIENT::Send(char* Format, ...) 
{
	va_list ap;	      // For arguments
	va_start(ap, Format);
	vsprintf(this->Sendbuffer, Format, ap);
	send(this->Socket, this->Sendbuffer, strlen(this->Sendbuffer), 0 );
	return this->Sendbuffer;
}

char* CLIENT::Recv() 
{
	int receivedBytes = recv(this->Socket, Recvbuffer, 1000, 0);
	Recvbuffer[receivedBytes] = 0;

	return receivedBytes < 0 ? "Disconnected" : this->Recvbuffer;
}

I'm sorry that i'm begging for help guys but I like everything. I thought maybe it is DirectX that manipulates the string itself, but before that I first wanted an second opinion.

Edit:
I forgot to mention that my server is not having any problems with receiving and parsing the packets. It parses the same way.

I've no idea how big your send and receive buffers are.

You're assuming a perfect transport mechanism (that is, each send ALWAYS sends the whole message, and recv always get exactly what send sent).
Neither of these things is actually true.
http://www.daniweb.com/forums/post1157666.html#post1157666

> Recvbuffer[receivedBytes] = 0;
I'm going to take a stab and think that you have char RecvBuffer[1000];
- you're screwed if recv() completely fills the buffer, and the \0 lands out of bounds
- you're screwed if recv returns -1, and you scribble off the other end instead.

> va_start(ap, Format);
You don't have a va_end() either.

> Recvbuffer[receivedBytes] = 0;
I'm going to take a stab and think that you have char RecvBuffer[1000];
- you're screwed if recv() completely fills the buffer, and the \0 lands out of bounds
- you're screwed if recv returns -1, and you scribble off the other end instead.

They are 255 bytes.

So what you are saying is that I need to redo my Recv() function because it might only get parts of the message?

Alright thanks.
Would it be a good way to send every packet, byte by byte?
And receive it, byte by byte?

Your receiver needs to know where one message ends, and the next one begins. There are many ways to do this, depending on what you're trying to do.

Two common ways are:
- fixed_width_count + variable_length_data
- variable_length_data + delimiter

The first is easier for the receiver, since it always knows how much to expect at any given moment.

You can receive a buffer using recv if you want, but you also need a second buffer to store an unused message fragment, where the end of a message is in the middle of a buffer.

Byte-by-Byte simplifies things, but isn't the most efficient.

But getting it working first is a priority, then tinker with the performance (by using a buffer say) later on.

Also why should I make a new one? I check all lengths of packets and they were equal to the strlen's. o-o.

Edit:
Nevermind, I just read your above post. Thanks alot man, if I get this working, ill message you :3.

What if I add some kind of delimiter in my packets like ";" or "$" and I scan for that so I know the packet ends, do you think that will work?
I'm trying getting it to work but I wanna know if it is a waste of effort.

Thanks alot!

> What if I add some kind of delimiter in my packets like ";" or "$" and I scan for that so I know the packet ends, do you think that will work?
That was the other choice I mentioned.

Oh nevermind! I completly understand now!
I really want to thank you!

Thanks alot dude, you helped me out!
~Solved

commented: Thanks, good luck - and enjoy! +19
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.