My problem description is as follows:
My C#
client sends a udp packet using sendto
. Because this is C#
, this is a byte array that I have constructed.
The C
server receives the packet using recvfrom
. Through wireshark, I have confirmed that the C#
program is sending the packet, and that the C
program is receiving it. The recvfrom
is not throwing any kind of error. But I am unable to extract any data out of the received packet. I receive it in a char array.
Specific details:
The UDP
packet that i send is a request. Both the c
program and the C#
program are aware of the structure of the request. But since i am sending an array of bytes over the wire, this structure is irrelevant (i think).
Code:
C#
:
Constructing the packet:
``
byte[] tmpB;
int j = 0;
char[] reqStr = rsField.reqStr;
for (; j < reqStr.Length; j++)
{
tmpB = BitConverter.GetBytes((char)reqStr[j]);
for (int ctr = 0; ctr < tmpB.Length; ctr++)
retVal[i++] = tmpB[ctr];
}//end of for
tmpB = BitConverter.GetBytes((UInt32)rsField.fieldLength);
for (int ctr = 0; ctr < tmpB.Length; ctr++)
retVal[i++] = tmpB[ctr];
tmpB = BitConverter.GetBytes((UInt32)rsField.fieldType);
for (int ctr = 0; ctr < tmpB.Length; ctr++)
retVal[i++] = tmpB[ctr];
//------------------------------------------------------------
tmpB = BitConverter.GetBytes((UInt32)ctField.camType);
for (int ctr = 0; ctr < tmpB.Length; ctr++)
retVal[i++] = tmpB[ctr];
tmpB = BitConverter.GetBytes((UInt32)ctField.fieldLength);
for (int ctr = 0; ctr < tmpB.Length; ctr++)
retVal[i++] = tmpB[ctr];
tmpB = BitConverter.GetBytes((UInt32)ctField.fieldType);
for (int ctr = 0; ctr < tmpB.Length; ctr++)
retVal[i++] = tmpB[ctr];
... `` As you can see, i have a mix of string and number fields. (These are not the only fields i have, code is shorted for readability)
C
:
``
char buf[1000];
memset(&buf,'\0',sizeof(buf));
length = recvfrom (i, &buf, sizeof(buf), 0,
(struct sockaddr *)&remoteAddr, &fromLen);
now = time(0);
if (length == -1) {
fprintf (stderr, "%s: recvfrom error - %m\n", ctime(&now));
continue;
}
unsigned long fieldType1 = strtoul(bufPtr,0,10);
bufPtr += 4 * sizeof(char);
unsigned long fieldLength1 = strtoul(bufPtr,0,10);
bufPtr += 4 * sizeof(char);
unsigned long res = strtoul(bufPtr,0,10);
printf("fieldType: %ld \t fieldLength: %ld \t res: %ld \t \n",fieldType1,fieldLength1,res);
... `` I am convinced that I am missing a fundamental aspect in this whole thing. Please help me find out what it is. Any help would be appreciated.
Thank you.
Once the bits have been written to the wire, it isn't C, C++, C#, Java, FORTRAN, COBOL, lisp, scheme, scala, or anything else. It's bits on a wire. That's the fundamental aspect you are missing. There's no structure to the data on the wire.
Once you read the data, it is up to you to take this collection of bytes and apply a structure to it. That means you'll need to know that the first four bytes represent a number, and the lower order byte is stored at offest 0 from the beginning of the payload, the next higher byte is at offset 1, the next higher byte is at offset 2 and the highest order byte is at offset 3. Your specific example might have nothing in common with the description above, but the idea of how to pack into bytes and unpack out of bytes is what you need to pay careful attention to.
Verify that at the lowest level you are writing all bytes. Keep a map of which data is in which bytes, and then write each side of the communication independently from the specification you just wrote. Don't get tempted to write whole integers / shorts / data structures to the packet without converting them to bytes; otherwise, you'll find that the machines on both ends might have different opinions on how integers / shorts / data structures are represented.
精彩评论