954,492 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

Terminating Zero Problem

Hello everyone,

I am dealing with this problem that I receive a buffer from a client, and when I try to output what the client sends to my program, it only shows everything till the first zero character.

#include <cstdio>
#include <winsock2.h>
#include <iostream>
#include <string>

using namespace std;

struct incSockets
{
	SOCKET sv;
	SOCKET cl;
};

void filter(char* packet)
{
	while(*packet != 0)
	{
		cout << "(" << int(*packet) << ")";
		packet++;
	}
		
	cout << endl;
}

int main(int argc, char** argv) {

	struct incSockets incs;

	const int iReqWinsockVer = 2;   

	WSADATA wsaData;

	if (WSAStartup(MAKEWORD(iReqWinsockVer,0), &wsaData)==0)
	{
		if (LOBYTE(wsaData.wVersion) >= iReqWinsockVer)
		{
			incs.cl = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);	
			size_t bytesReceived;
			
			if (incs.cl==INVALID_SOCKET)
			{
				//error
			}
							
			sockaddr_in clSockAddr;
			
			memset(&clSockAddr, 0, sizeof(clSockAddr));
			
			clSockAddr.sin_family = AF_INET;
			clSockAddr.sin_port = htons(1339);
			clSockAddr.sin_addr.S_un.S_addr = INADDR_ANY;

			if (bind(incs.cl, (sockaddr*)(&clSockAddr), sizeof(clSockAddr))!=0)
			{
				//error	
			}
			
			char buffer[1024];
			int fromlen = 10240;

			while(true) {
				bytesReceived = recvfrom(incs.cl, buffer, 1024, 0, (struct sockaddr *)&clSockAddr, &fromlen);
				
				if(bytesReceived < 0) {
					//error
				}
				
			
				//When I do this, it shows me way more. 
				//cout << int(buffer[0]) << int(buffer[1]) << int(buffer[2]) << int(buffer[3]) << int(buffer[4]) << int(buffer[5]) << int(buffer[6]) << int(buffer[7]) << endl;
				
				//Now it only shows me the first 5 characters. The sixth is a 0.
				filter(buffer);
			}
			
			closesocket(incs.cl);
		}
		else
		{
			// Required version not available
		}

		// Cleanup winsock
		if (WSACleanup()!=0)
		{
			// cleanup failed
		}
	}
	else
	{
		//  startup failed
	}
    return 0;
}


I hope someone can help me solve this problem.

Thanks in advance.

Schoorsteen
Light Poster
44 posts since Aug 2009
Reputation Points: 10
Solved Threads: 3
 
void filter(char* packet)
{
	while(*packet != 0)
	{
		cout << "(" << int(*packet) << ")";
		packet++;
	}	
	cout << endl;
}


Hi, I've never written a program like this before, but look at the condition you place on the loop : while(*packet != 0)

That'll stop whenever *packet == 0

harry010
Light Poster
35 posts since Aug 2009
Reputation Points: 10
Solved Threads: 3
 

How should I finish the while-loop in that case.
When you got

int i = {1, 2, 3, 4};
int* p = i;


When you loop that with the filter function it will show: (1)(2)(3)(4)
or something like it.

If I don't do the != 0 it will show
(1)(2)(3)(4) followed by a lot of errors and finally a crashing program.

How would I be able to solve that?

Schoorsteen
Light Poster
44 posts since Aug 2009
Reputation Points: 10
Solved Threads: 3
 

use a for loop.

firstPerson
Senior Poster
3,923 posts since Dec 2008
Reputation Points: 841
Solved Threads: 608
 

What should the conditions of this for-loop be in that case?

Thank you both for responding by the way.

Schoorsteen
Light Poster
44 posts since Aug 2009
Reputation Points: 10
Solved Threads: 3
 

If I am reading correctly, you want to show packet as an int, via this
function?

void filter(char* packet)
{
	while(*packet != 0)
	{
		cout << "(" << int(*packet) << ")";
		packet++;
	}	
	cout << endl;
}
firstPerson
Senior Poster
3,923 posts since Dec 2008
Reputation Points: 841
Solved Threads: 608
 

That's correct, yes.

Schoorsteen
Light Poster
44 posts since Aug 2009
Reputation Points: 10
Solved Threads: 3
 

Is the string a char of digits or characters?

firstPerson
Senior Poster
3,923 posts since Dec 2008
Reputation Points: 841
Solved Threads: 608
 

Characters.

Schoorsteen
Light Poster
44 posts since Aug 2009
Reputation Points: 10
Solved Threads: 3
 
void filter(char* packet)
{
    int i = 0;
	while(packet[i])
	{
		cout << "(" << int(packet[i]) << ")";
		i++;
	}	
	cout << endl;
}
firstPerson
Senior Poster
3,923 posts since Dec 2008
Reputation Points: 841
Solved Threads: 608
 

never mind what i'm saying

harry010
Light Poster
35 posts since Aug 2009
Reputation Points: 10
Solved Threads: 3
 

That still doesn't work, it prints the first 5 characters, but not the following characters.

Currently it prints
(83)(65)(77)(80)(127)
which means:
SAMP and the 127 is the start from my local IP, which should be (127)(0)(0)(1).

Schoorsteen
Light Poster
44 posts since Aug 2009
Reputation Points: 10
Solved Threads: 3
 

Then your problem is the buffer thats being passed to it. I does
not contain what you want.

I assume that the problem is here:

bytesReceived = recvfrom(incs.cl, buffer, 1024, 0, (struct sockaddr *)&clSockAddr, &fromlen);


Check if bytesReceived is the correct number of bytes you want to recieve.

firstPerson
Senior Poster
3,923 posts since Dec 2008
Reputation Points: 841
Solved Threads: 608
 

Sorry, i shouldn't be trying to answer this-I'm just confusing things with my nonsense responses.

harry010
Light Poster
35 posts since Aug 2009
Reputation Points: 10
Solved Threads: 3
 

when I do

void filter(char* packet)
{

	for(int i = 0; i < 8; i++)
	{
		cout << "(" << int(*packet) << ")";
		packet++;
	}
		
	cout << endl;
}


It print's
(83)(65)(77)(80)(127)(0)(0)(1)
though, so that would mean the buffer contains that information right?

Schoorsteen
Light Poster
44 posts since Aug 2009
Reputation Points: 10
Solved Threads: 3
 

"will evaluate to false when packet[i]==0"

Yes thats correct. The 0 identifies the end of the string. Any further
then its junk.

firstPerson
Senior Poster
3,923 posts since Dec 2008
Reputation Points: 841
Solved Threads: 608
 

When I cout the receivedBytes I get this number 4294967295. Would this be right?

Schoorsteen
Light Poster
44 posts since Aug 2009
Reputation Points: 10
Solved Threads: 3
 

"will evaluate to false when packet[i]==0"

Yes thats correct. The 0 identifies the end of the string. Any further then its junk.

Sorry, I didn't understand the original post at first. I shouldn't have posted anything.

harry010
Light Poster
35 posts since Aug 2009
Reputation Points: 10
Solved Threads: 3
 

when I do

void filter(char* packet)
{

	for(int i = 0; i < 8; i++)
	{
		cout << "(" << int(*packet) << ")";
		packet++;
	}
		
	cout << endl;
}

It print's (83)(65)(77)(80)(127)(0)(0)(1) though, so that would mean the buffer contains that information right?


Thats weird. Try cout<

firstPerson
Senior Poster
3,923 posts since Dec 2008
Reputation Points: 841
Solved Threads: 608
 

I think you're all missing the point. Sockets doesn't send immediately.

Send Packet 5
Send Packet 8
Send Packet 7

It won't necessarily arrive as three packets 5 then 8 then 7 bytes in length.
It may arrive as 2 packets 5+8=13 and 7
or 5 and 15
or a single packet 20 bytes long!
The packet is sent on an interval basis, not immediately so sometimes packets get combined as a single packet of multiple messages!

So instead!

void filter( char* packet, uint nPacketLen )
{
    while (nPacketLen)
    {
         while ((*packet != 0) && nPacketLen)
        {
	cout << "(" << int(*packet) << ")";
               packet++;
               nPacketLen--
       }
        cout << endl;
   }
}
wildgoose
Practically a Posting Shark
896 posts since Jun 2009
Reputation Points: 546
Solved Threads: 99
 

This question has already been solved

Post: Markdown Syntax: Formatting Help
You