LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Using ServerTCPWrite() to transport a structure data.

I have defined a structure like follows :

struct dataWrite{
int event;
char message[256];
};

How to use ServerTCPWrite() to transmit it to the client ? Thanks.

David
0 Kudos
Message 1 of 6
(3,551 Views)
Being in your trouble, I will create a string and pass it to the ServerTCPWrite function. Something like

dataWrite xx;

sprintf (msg, "%d;%s", xx.event, xx.message);
ServerTCPWrite (handle, msg, strlen (msg), 1000);

The receiver can then rebuild the structure

char msg[256];
dataWrite xx;

ClientTCPRead(tcpH, msg, 256, 1000);
Scan (msg, "%d[x]%s", &xx.event, xx.message);

Hope this helps
Roberto


Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 2 of 6
(3,551 Views)
I'll try and offer a suggestion using pseudo code, so no guarentee's it will work...

First off, lets assume that you have a header file with the define for you struct in it.

struct dataWrite{
int event;
char message[256];
};


In the server app, we create

dataWrite myStructToSend;

The TCP Write function sends out bytes. How many bytes does it send, well that is up to you.

So we can calculate the size of the struct by using

long myStructSize = size of (myStructToSend)

So now we know how many bytes to send.

(Its also one reason why the server and client should share the header file where the struct is defined, so that if you change the size of the struct with the addition of a new parameter, or remove one, both applications will have the new si
ze (but you will need to recompile and issue both the server and exe using this method)).

Now we need to know what to send.

long *ptrToMyStruct = *myStructToSend;

Now we know where the data starts since we have the pointer to the start of the structure, and since we have the size, its just a case of stepping through the memory from the start of the ptr to the end of the struct, transmitting the data (multiple sends or one single one, can't remember the TCP write functions off hand).

To read the data in (within the client), we create say:

dataWrite myStructToReceive;

Do the same things above, i.e.

i. get the size.
ii. get a ptr to the myStructToReceive
iii. start reading from the server, writing the rx'ed data at the memory location pointed to by myStructToReceive,


Hope this explains it somehow. It may not be exact, but hopefully you can get the jist of it.

Sending info in a string is just as easy, and then you could parse the string. This could be ok
for simple structs, but you would probably spend more time parsing the complex structs than you would really want to.

Regards

Chris
0 Kudos
Message 3 of 6
(3,551 Views)
Well, this was my first attempt while I was developing an application a few years ago with two programs communicating via TCP.

In my application I had a complex structure including some dates in SYSTEMTIME format and a char field with answers from an instrument. I tried to pass the structure to the ServerTCPWrite casted to an array of chars, but unfortunately this resulted in incomplete structure received by the client.

I assumed this was because of ascii 0 chars inside the string or inside the SYSTEMTIME structure, but urged to ship the application had no time to deep into this problem and resolved to format a string to pass to TCP function and parse it in the client.

This was with CVI 4, maybe now this problem was solved.

Roberto


Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 4 of 6
(3,551 Views)
/***************************************************************
There is no need to worry about parsing; just receive the
data directly into your struct.

You can use the #pragma pack preprocessor directive to ensure
that there is no unused space between the struct members (not
normally an issue unless sending structs containing a large
number of elements). Also, use a typedef to ease handling.
***************************************************************/

// Do this for both SERVER & CLIENT
#pragma pack(push,1)
struct dataWrite_s
{
int event;
char message[256];
};
#pragma pack(pop)
typedef struct dataWrite_s s_dataWrite, *p_s_dataWrite;

s_dataWrite dataWrite;
p_s_dataWrite pData; // may be useful
int handle; // handle for the conver
sation
....
pData = &dataWrite;

// Establish the conversation, etc.

// SERVER code
// Put some velues into the struct
dataWrite.event = 0x12345678;
sprintf (dataWrite.message, "This is the message.\n");
// Send the message
ServerTCPWrite (handle, &dataWrite, sizeof (s_dataWrite), 1000);

// CLIENT code
// Receive the message
ClientTCPRead (handle, &dataWrite, sizeof (s_dataWrite), 1000);
// Message contents now available in dataWrite


Regards

Colin.
0 Kudos
Message 5 of 6
(3,551 Views)
Thanks All!

David
0 Kudos
Message 6 of 6
(3,551 Views)