C TCP client and .NET TCP server?

L

Lothar Behrens

Hi,

I have a client that sends a structure like this:

typedef struct packet_struct{
int16_t p1
int16_t p2
u_int32_t p3;
int16_t p4
char buffer[10240];
}packet;

The packet structure gets filled with random values and then filled
with the real values. The string is a null terminated C string. Then
the buffer gets sent over the wire with a buffer size of 10252 via
sizeof().

After figuring out that the alingment fools me I changed my
ClientSocket recieve buffer size to 10252.

Now I get random bytes at the end of the string in my recived buffer
like this:

int bufferSize = 10252;
myClientSocket.ReceiveBufferSize = bufferSize;

byte[] buffer = new byte[bufferSize];

lock (parameterCarrier)
{
int status = myClientSocket.Receive(buffer);

To avoid this and because there is an alingment, I strip the last two
bytes of the buffer part.

I got this because of sniffing the packet sent over the wire and I
have seen the starting of the buffer with an
offset of ten bytes.

Thus I assume the alingment is done at the end of the structure at all
and thus I get the random values.

Is that correct, or do I have trapped another pittfall?

Thanks

Lothar
 
A

Arne Vajhøj

I have a client that sends a structure like this:

typedef struct packet_struct{
int16_t p1
int16_t p2
u_int32_t p3;
int16_t p4
char buffer[10240];
}packet;

The packet structure gets filled with random values and then filled
with the real values. The string is a null terminated C string. Then
the buffer gets sent over the wire with a buffer size of 10252 via
sizeof().

After figuring out that the alingment fools me I changed my
ClientSocket recieve buffer size to 10252.

Now I get random bytes at the end of the string in my recived buffer
like this:

int bufferSize = 10252;
myClientSocket.ReceiveBufferSize = bufferSize;

byte[] buffer = new byte[bufferSize];

lock (parameterCarrier)
{
int status = myClientSocket.Receive(buffer);

To avoid this and because there is an alingment, I strip the last two
bytes of the buffer part.

I got this because of sniffing the packet sent over the wire and I
have seen the starting of the buffer with an
offset of ten bytes.

Thus I assume the alingment is done at the end of the structure at all
and thus I get the random values.

Is that correct, or do I have trapped another pittfall?

Alignments are very compiler/platform specific.

But the explanation sounds very likely.

int16_t p1 // must be aligned on x2 - no problem
int16_t p2 // must be aligned on x2 - no problem
u_int32_t p3 // must be aligned on x4 - no problem
int16_t p4 // must be aligned on x2 - no problem
char buffer[10240] // must be aligned on x1 - no problem
next element in array // must be aligned on x4 (otherwise its p3
would not be aligned) - need to pad struct with 2 bytes to make it

Arne
 
L

Lothar Behrens

I have a client that sends a structure like this:
typedef struct packet_struct{
         int16_t   p1
         int16_t   p2
         u_int32_t p3;
         int16_t   p4
         char      buffer[10240];
         }packet;
The packet structure gets filled with random values and then filled
with the real values. The string is a null terminated C string. Then
the buffer gets sent over the wire with a buffer size of 10252 via
sizeof().
After figuring out that the alingment fools me I changed my
ClientSocket recieve buffer size to 10252.
Now I get random bytes at the end of the string in my recived buffer
[...]
Is that correct, or do I have trapped another pittfall?

Without a concise-but-complete code example, it's impossible to comment
on what problems, if any, there are in your code.

Arne's comment about the alignment issue is correct, but may or may not
be relevant depending on how you're processing the byte[] that receives
the data.  You already seem to be aware that the client is sending 10252
bytes, not the 10250 that the structure members require, so it's not
necessarily the case that structure alignment is the main problem.

Based on what little code you did post, I'd say a much more likely
problem with your code is to assume that the Receive() method fills the
provided buffer before returning.  It is not required to and often will
not.  The return value isn't just "status".  It's an actual count of the
actual bytes that were received.

Especially with a data structure that large, it would not be all that
uncommon for it to be received in parts, rather than filling your buffer
all at once.  Unless your code is correctly handling that scenario, it's
wrong.

By the way, if you have any control over the protocol, I would get rid
of that fixed-length char[] buffer, unless 99.9% of the time the entire
char[] is used for the string.  That's an _awful_ lot of wasted space
and bandwidth otherwise.

Pete

The size of the structure is usually 1024 bytes, but our demand
exceeds the size. Thus we have changed that. Also to be compatible we
don't use variable sizes.
The main goal for us is to replace the C/C++ code by our own .NET
code. But until that is done I have to use plain TCP at all. Later we
think about using WCF and for the Linux related stuff may be CORBA
(may be ACE or MICO) and IIOP.NET or SOAP at all to replace the plain
TCP communication.

An option for us may be a rewrite of the client as it will be still
integratable in the existing system, thus we have all the choices as
long it runs also on Linux.

To the complexity of the Socket API I assume it would not be less
complex in .NET. Right?

I know if I add dynamic sized data structures, I have to put the size
into a size variable in the structure and recieve the varying part in
at least a second step.
To do that right or fix my issues in my code at all:

Is there a good .NET Network programming book at the level of sockets
and TCP?

Or can I pick up a more general TCP networking guide?

Thanks

Lothar
 

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

Top