Cannot See It!

  • Thread starter Ramiro Barbosa, Jr.
  • Start date
R

Ramiro Barbosa, Jr.

All,

Any ideas why the following code prints zeros for the message id,
number of packets and sequence number as shown in the sample output
below? Somehow I am not being able to access the contents of my
'incomingDataBuffer' array. I have also included some values from the
respective MSVC 6.0 debug session.

Thank you!

-RB

-------------------------------------------------------------------------------
#include<windows.h>
#include<iostream>
#include<string>
#include<stdio.h>
#include<stdlib.h>

using namespace std;

int main(int argc, char * argv[])
{
WSADATA wsaData;
SOCKADDR_IN serverAddress;
SOCKADDR_IN clientAddress;
SOCKET receivingSocket;
int port = 7797;
int length;
char incomingDataBuffer[600];

int ret = WSAStartup(MAKEWORD(2,0), &wsaData);

if (ret != 0)
{
int errorCode = WSAGetLastError();
cout<<"ERROR ["<<errorCode<<"] initializing WinSock!"<<endl;
exit(1);
}
if (LOBYTE(wsaData.wVersion)!= 2 || HIBYTE(wsaData.wVersion)!= 0)
{
cout<<"Invalid Winsock Version"<<endl;
WSACleanup();
exit(1);
}
if (port < 1)
{
cout<<"Invalid UDP port"<<endl;
exit(1);
}
if ((receivingSocket = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
cout<<"Unable to create socket"<<endl;

memset((char*)&serverAddress,0,sizeof(serverAddress));
serverAddress.sin_family = AF_INET;
serverAddress.sin_addr.s_addr = htons(INADDR_ANY);
serverAddress.sin_port = htons(port);

int status = bind(receivingSocket,
(sockaddr*)&serverAddress,sizeof(serverAddress));

if (status < 0)
{
cout<<"Error: bind() failed."<<endl;
exit(1);
}

// join multicast group...
struct ip_mreq mreq;

mreq.imr_multiaddr.s_addr = inet_addr("225.0.0.100");
mreq.imr_interface.s_addr = INADDR_ANY;

// add membership/subscribe to group...
status = setsockopt(receivingSocket, IPPROTO_IP,
IP_ADD_MEMBERSHIP,(char*)&mreq, sizeof(mreq));

memset(&clientAddress, 0, sizeof(clientAddress));
length = sizeof(clientAddress);

for(;;)
{
int numberOfBytesReceived = 0;

numberOfBytesReceived =
recvfrom(receivingSocket,incomingDataBuffer,600,0,(sockaddr*)&clientAddress,&length);

if (numberOfBytesReceived == SOCKET_ERROR)
{
int wsaError = WSAGetLastError();
cout<<"Winsock error ["<<wsaError<<"]"<<endl;
// leave/unsubscribe from multicast group...
status = setsockopt(receivingSocket, IPPROTO_IP,
IP_DROP_MEMBERSHIP,(char*)&mreq, sizeof(mreq));
exit(1);
}
else
{
cout<<endl<<"Received ["<<numberOfBytesReceived<<"]
bytes"<<endl;

// the ID is the first 8 bytes of the header...
int id = atoi(strncpy(new char[32],incomingDataBuffer,8));
// the total number of packets are the 15th and 16th bytes
of the header...
int totalPackets = atoi(strncpy(new char[32],
incomingDataBuffer + 14, 2));
// the sequence number is 13th and 14th byte of the
header...
int sequenceNumber = atoi(strncpy(new char[32],
incomingDataBuffer + 12, 2));

cout<<"Message ID.....: "<<id<<endl;
cout<<"Total Packets..: "<<totalPackets<<endl;
cout<<"Sequence Number: "<<sequenceNumber<<endl;
}
}
closesocket(receivingSocket);
return(0);
}

/*
Sample output:
--------------------
Received [538] bytes
Message ID.....: 0
Total Packets..: 0
Sequence Number: 0

Received [522] bytes
Message ID.....: 0
Total Packets..: 0
Sequence Number: 0

Received [522] bytes
Message ID.....: 0
Total Packets..: 0
Sequence Number: 0

Received [530] bytes
Message ID.....: 0
Total Packets..: 0
Sequence Number: 0

Received [530] bytes
Message ID.....: 0
Total Packets..: 0
Sequence Number: 0

In the MS-Visual C++/-EE-6.0 debugger:

Values before the "recvfrom" call:
-------------------------------------
+ &clientAddress 0x0012fdd0
+ incomingDataBuffer 0x0012fb6c
"ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ"
+ &length 0x0012fdc4
numberOfBytesReceived 0
receivingSocket 2972

Values after the "recvfrom" call:
-------------------------------------
+ &clientAddress 0x0012fdd0
+ incomingDataBuffer 0x0012fb6c ""
+ &length 0x0012fdc4
numberOfBytesReceived 514
receivingSocket 2972
*/
 
J

John Harrison

Ramiro Barbosa said:
All,

Any ideas why the following code prints zeros for the message id,
number of packets and sequence number as shown in the sample output
below? Somehow I am not being able to access the contents of my
'incomingDataBuffer' array. I have also included some values from the
respective MSVC 6.0 debug session.

I'm guessing here but I think you do not understand how to decode the
message id etc from the packet.

I think the numbers are in binary not in ASCII which is what you are
assuming. For instance I think you would have more luck with the following

int sequenceNumber = (unsigned char)incomingDataBuffer[12] + 256*(unsigned
char)incomingDataBuffer[13];

or maybe the other way round

int sequenceNumber = 256*(unsigned char)incomingDataBuffer[12] + (unsigned
char)incomingDataBuffer[13];

Try both ways (which is right depends on which order the bytes are in).

Similar methods for the total packets and message id. Althoug with the
message id you have to figure out how to deal with an eight byte integer.

But as I say, I'm guessing.

john
 
R

Raymond Martineau

All,

Any ideas why the following code prints zeros for the message id,
number of packets and sequence number as shown in the sample output
below? Somehow I am not being able to access the contents of my
'incomingDataBuffer' array. I have also included some values from the
respective MSVC 6.0 debug session.

Thank you!

// the ID is the first 8 bytes of the header...
int id = atoi(strncpy(new char[32],incomingDataBuffer,8));

That's a memory leak. You might want to use a static buffer of 32
charaters, or assign the 32 characters to a buffer to be deleted after use.

Anyway, atoi only works on string representation of a number. It will not
work on binary representations of a number, which is what I suspect is the
case. Also, when dealing with sockets, the numbers presented might not
match up with the expected value - thus you will have to find a way to
reverse the bytes of the number.

One last thing: with strncpy, a null character is not appended if all 8 or
so characters are filled up. You should add a null character manually, or
otherwise ensure that the buffer of 32 characters is initially clean.
// the total number of packets are the 15th and 16th bytes
of the header...
int totalPackets = atoi(strncpy(new char[32],
incomingDataBuffer + 14, 2));
// the sequence number is 13th and 14th byte of the
header...
int sequenceNumber = atoi(strncpy(new char[32],
incomingDataBuffer + 12, 2));

Same applies with these two assignments as well.

Values after the "recvfrom" call:

You might want to view the contents of "incomingDataBuffer". This will
give you a better look at what is going on with how the header information
is stored.
 
R

Ramiro Barbosa, Jr.

All,

Thanks a lot for your valuable input. I was indeed considering the
input from the socket as ASCII and that was wrong. I revised my
program and I have adopted the ideas that you have given me, thus
getting some very good results. I am attaching my revised program
which still has one problem. Please check the commeents in the code
towards the end of the program. Also, if John Harrison gets to see
this message I would like to know/understand why he suggested me to
take for example the value in a subindex of the incoming buffer array
and cast it to an unsigned char then multiply by 256.

Thank you all, and best regards!

-RB


All,

Any ideas why the following code prints zeros for the message id,
number of packets and sequence number as shown in the sample output
below? Somehow I am not being able to access the contents of my
'incomingDataBuffer' array. I have also included some values from the
respective MSVC 6.0 debug session.

Thank you!

// the ID is the first 8 bytes of the header...
int id = atoi(strncpy(new char[32],incomingDataBuffer,8));

That's a memory leak. You might want to use a static buffer of 32
charaters, or assign the 32 characters to a buffer to be deleted after use.

Anyway, atoi only works on string representation of a number. It will not
work on binary representations of a number, which is what I suspect is the
case. Also, when dealing with sockets, the numbers presented might not
match up with the expected value - thus you will have to find a way to
reverse the bytes of the number.

One last thing: with strncpy, a null character is not appended if all 8 or
so characters are filled up. You should add a null character manually, or
otherwise ensure that the buffer of 32 characters is initially clean.
// the total number of packets are the 15th and 16th bytes
of the header...
int totalPackets = atoi(strncpy(new char[32],
incomingDataBuffer + 14, 2));
// the sequence number is 13th and 14th byte of the
header...
int sequenceNumber = atoi(strncpy(new char[32],
incomingDataBuffer + 12, 2));

Same applies with these two assignments as well.

Values after the "recvfrom" call:

You might want to view the contents of "incomingDataBuffer". This will
give you a better look at what is going on with how the header information
is stored.
 
R

Ramiro Barbosa, Jr.

Sorry, forgot to post the code:

#include<windows.h>
#include<iostream>
#include<string>

using namespace std;

int main(int argc, char * argv[])
{
const int MAX = 65535;
WSADATA wsaData;
SOCKADDR_IN serverAddress;
SOCKADDR_IN clientAddress;
SOCKET receivingSocket;
int port = 7797;
int length;
char incomingDataBuffer[MAX];

int ret = WSAStartup(MAKEWORD(2,0), &wsaData);

if (ret != 0)
{
int errorCode = WSAGetLastError();
cout<<"ERROR ["<<errorCode<<"] initializing WinSock!"<<endl;
exit(1);
}
if (LOBYTE(wsaData.wVersion)!= 2 || HIBYTE(wsaData.wVersion)!= 0)
{
cout<<"Invalid Winsock Version"<<endl;
WSACleanup();
exit(1);
}
if (port < 1)
{
cout<<"Invalid UDP port"<<endl;
exit(1);
}
if ((receivingSocket = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
cout<<"Unable to create socket"<<endl;

memset((char*)&serverAddress,0,sizeof(serverAddress));
serverAddress.sin_family = AF_INET;
serverAddress.sin_addr.s_addr = htons(INADDR_ANY);
serverAddress.sin_port = htons(port);

int status = bind(receivingSocket,
(sockaddr*)&serverAddress,sizeof(serverAddress));

if (status < 0)
{
cout<<"Error: bind() failed."<<endl;
exit(1);
}

// join multicast group...
struct ip_mreq mreq;

mreq.imr_multiaddr.s_addr = inet_addr("225.0.0.100");
mreq.imr_interface.s_addr = INADDR_ANY;

// add membership/subscribe to group...
status = setsockopt(receivingSocket, IPPROTO_IP,
IP_ADD_MEMBERSHIP,(char*)&mreq, sizeof(mreq));

memset(&clientAddress, 0, sizeof(clientAddress));
length = sizeof(clientAddress);

for(;;)
{
for(int count = 0; count < MAX; count++)
{
incomingDataBuffer[count] = '\0';
}
int numberOfBytesReceived = 0;

numberOfBytesReceived =
recvfrom(receivingSocket,incomingDataBuffer,MAX,0,(sockaddr*)&clientAddress,&length);

if (numberOfBytesReceived == SOCKET_ERROR)
{
int wsaError = WSAGetLastError();
cout<<"Winsock error ["<<wsaError<<"]"<<endl;
// leave/unsubscribe from multicast group...
status = setsockopt(receivingSocket, IPPROTO_IP,
IP_DROP_MEMBERSHIP,(char*)&mreq, sizeof(mreq));
exit(1);
}
else
{
cout<<endl<<"Number of bytes in packet
received.....["<<numberOfBytesReceived<<"]"<<endl;

// this is not working!

/* DETAILS OF PROBLEM:
- messageId variable below should result in a big number which
looks something like
"1098717778156" (the number of miliseconds from Jan 01, 1970 used
as the ID).

- The data is coming from a Java server which sends the 'id' in
the first 8 bytes of
the header. The Java value of that ID is a long. Below is the
buffer showing what I
am receiving.

/* The following are values printed from a debug session (MSVC 6.0)
//---------------------------------------------------------------------------
// ARRAY DECIMAL BINARY
//---------------------------------------------------------------------------
incomingDataBuffer[0] 0 ''
incomingDataBuffer[1] 0 ''
incomingDataBuffer[2] 0 ''
incomingDataBuffer[3] -1 'some binary here'
incomingDataBuffer[4] -47 'some binary here'
incomingDataBuffer[5] -119 'some binary here'
incomingDataBuffer[6] 2 'some binary here'
incomingDataBuffer[7] 25 'some binary here'

// this is what I am doing but I am getting a much smaller number
as far as the number of digits.
// I need to fit the 8 incoming bytes in a C++ type. However, C++
long is only 4 bytes
// in my platform (Win2K).

// These are the sizes of types in my platform:
---------------------------------------------------------------------
C++ Windows Types/Sizes:
---------------------------------------------------------------------
Size int: 4
Size long: 4
Size double: 8
Size short: 2
Size long int: 4

----------------------------------------------------------------------
Java type sizes
----------------------------------------------------------------------
Type Bits Min Value Max Value
byte 8 -128 127
short 16 -32,768 32,767
int 32 -2,147,483,648 2,147,483,647
long 64 -9,223,372,036,854,775,808
9,223,372,036,854,775,807
----------------------------------------------------------------------
*/
// not working...
long messageID =
256 * (unsigned char)incomingDataBuffer[0]
+ (unsigned char)incomingDataBuffer[1]
+ (unsigned char)incomingDataBuffer[2]
+ (unsigned char)incomingDataBuffer[3]
+ (unsigned char)incomingDataBuffer[4]
+ (unsigned char)incomingDataBuffer[5]
+ (unsigned char)incomingDataBuffer[6]
+ (unsigned char)incomingDataBuffer[7];

// working!
int messageSize =
256 * /*(unsigned char)incomingDataBuffer[8] */ // check if this
guy is empty....
/*+ (unsigned char)incomingDataBuffer[9] */
(unsigned char)incomingDataBuffer[10]
+ (unsigned char)incomingDataBuffer[11];
cout<<"Message Size...: "<<messageSize<<endl;

// working!
int sequenceNumber =
256*(unsigned char)incomingDataBuffer[12]
+ (unsigned char)incomingDataBuffer[13];
cout<<"Sequence Number: "<<sequenceNumber<<endl;

// working!
int totalPackets =
256*(unsigned char)incomingDataBuffer[14] + (unsigned
char)incomingDataBuffer[15];
cout<<"Total Packets..: "<<totalPackets<<endl;

// working!
int isEncrypted = (unsigned char)incomingDataBuffer[16];
cout<<"Encryption.....: "<<((isEncrypted == 1) ? "Encrypted" :
"Not encrypted")<<endl;

// working!
int isCompressed = (unsigned char)incomingDataBuffer[17];
cout<<"Compression....: "<<((isCompressed == 1) ? "Compressed" :
"Not compressed")<<endl;
}
}
closesocket(receivingSocket);
return(0);
}
 
J

John Harrison

Ramiro Barbosa said:
All,

Thanks a lot for your valuable input. I was indeed considering the
input from the socket as ASCII and that was wrong. I revised my
program and I have adopted the ideas that you have given me, thus
getting some very good results. I am attaching my revised program
which still has one problem. Please check the commeents in the code
towards the end of the program. Also, if John Harrison gets to see
this message I would like to know/understand why he suggested me to
take for example the value in a subindex of the incoming buffer array
and cast it to an unsigned char then multiply by 256.

Thank you all, and best regards!

Because on some platforms chars are signed quantities, so you cast to
unsigned char to be sure.

john
 
R

Ramiro Barbosa, Jr.

John,

Why you multiply by 256?

-RB

John Harrison said:
Because on some platforms chars are signed quantities, so you cast to
unsigned char to be sure.

john
 
J

John Harrison

Ramiro Barbosa said:
John,

Why you multiply by 256?

A byte is eight bits, so it can be any number from 0 - 255. When you have
two bytes representing a number in binary, it's like a two digit number with
each byte being one digit. But its a base 256 number so you multiply the
most significant byte by 256.

john
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top