Main Site Documentation

TCP Message design question


#1

Don’t know if it’s allowed to answer this kind of questions here, so if it’s not the case, mods feel free to remove it.

So, I’m planning on transmitting data between a PC and a Fez Cobra over TCP. What would be the best way to construct the messages. I know i can send plain text, but I’m sure there’s a more elegant and robust way to do this. Can you point me to some resources or provide more details?

The messages would contain an id, command, data.

Thanks in advance


#2

Is it going from the PC to the Cobra or Cobra to PC?

You’re probably looking at having a socket server on one end and sending XML across.


#3

Both ways.

PC will ask for data at specified interval, and cobra will need to send events as they arrive on the IO pins. Guess I also want some sort of buffer on the Cobra. When I’m updating my PC app, the cobra should buffer/queue the messages and send them again when my app is online again. Need to investigate how i can accomplish that.

Would xml (as you suggested) be the way to go?

Greetings


#4

Ah, ok, you you need a socket server on the Cobra then.

XML is designed for just these kind of requirements.


#5

There are several ways to handle what you want to do - it just depends on how fancy you want to get. Like you said, you can send simple fixed-width strings across the socket if it suits your needs. Using XML is also an option, and might be a good one especially if you’re going to send multiple messages in batches to the PC. There’s also DPWS, but that’s probably overkill for what you want to do. There is no one “right” way to do it - just whatever makes sense for your app. XML or delimited strings are probably the way to go if you have simple messages to send.

If you need to support communication initiated from both the Cobra and the PC to each other, you’ll need to set up a TCP socket listener on both of them to wait for incoming connection requests. The .NET code for this should be very similar for the full .NET framework and the Micro Framework.


#6

Mark and others, thanks so far for the info.

After some googling i found this article: http://www.eggheadcafe.com/articles/20021125.asp, while MSMQ would solve the buffer/queue part (I could easily setup a queue on the pc hosting my app), it is not available in the Microframework. Is there an alternative way?


#7

You’ll have to roll your own message queueing code. Here’s something I might do for your queueing issue on the Cobra. I don’t know the exact requirements of your app, but this would be a very basic approach.

When the Cobra generates a message that needs to be sent to the PC, I would persist that message to local storage on the SD card (either one message per file or several messages in a file). I would then have a separate thread running that periodically checked the file(s) for outstanding messages that need to be sent, send them to the remote PC if a connection is available, then delete the local messages. Of course you would need to make sure to handle concurrency issues on the files so that both processes weren’t trying to write to the files at the same time. This would essentially be a very simple version of MSMQ. Hope that helps?


#8

The first question that needs to be asked is the message rate. How many message per second?

If the rate is high, then you will need a very efficient encode/decode scheme. XML would not be the answer. A binary solution would be best.

For low rates, if possible, I would recommend delimited strings. The encode/decode routines would work on micro and full version of .NET.


#9

The rate will not be high.
Got any link handy regarding the encode/decode routines?


#10

I would just build a string for encoding such as :

string msg1 = "cmdx," + variable1.ToString() + '\r';

Decoding would be:

String incomingMessage; // created from inbound buffer '\r' stripped
// seperators to seperate parts of message
char[] seperators = new char[] {','};
// split message into parts
String[] parts = incomingMessage.Split(seperators);
String receivedCommand = parts[0]; // contains cmdx
int variable1= parts[1].ToString();

/


#11

Strings are easy to use and human-read (debug) but they take a lot of processing from FEZ. Do not use strings if you are planning on transferring thousands or arguments back and forth.


#12

That won’t be the case (only strings of max 100 characters every now and then)

Sorry if this sounds as a dumb question, but i never did this kind of stuff.
In order to send AND receive TCP messages between pc and Fez Cobra, I need a TCPClient and a TCPListener on both pc and cobra, right?

Greetings


#13

yes correct


#14

[quote]In order to send AND receive TCP messages between pc and Fez Cobra, I need a TCPClient and a TCPListener on both pc and cobra, right?
[/quote]

I think Gus and I differ on this question. :’(

A TCPClient initiates a call to a TCPListener. The TCPListener, which had an outstanding Accept method, returns a new socket through which communications can be done with the TCPClient socket. The communications can go both ways over the sockets.

This architecture is called client/server.

Only the side that receives an incoming connection needs a TCPListener. In most applications, this is only one of the sides.

So, if you application has a program on a PC which needs to get to a FEZ every few minutes to pick up data, then the PC would only need a client and the FEZ would need a listener.

I guess you could have an application where both sides need to initiate the session/connection, and in this case, both sides would need a listener and a client.

So… my answer is “in most cases no”


#15

Mike,

allow me to explain a bit more what i’m looking for.

The Fez Cobra will have a bunch of sensors attached. Some sensors are responsible to count pulses, other sensors will measure temperature, and other sensors will catch events like when a door opens or closes.

What I would like to do is to sent the counters and temp sensor values when requested by the pc. Regarding the events happening on the Cobra, they need to be send to the pc (without the pc asking for it).

Thanks for any advice or suggestions.


#16

Ah!

In the situation you describe you would need listeners on both sides.

The listener on the PC is waiting for call from the Cobra to be told about events.

The listener on the Cobra is waiting for call from the PC to request measurement.

GUS WAS RIGHT! ???


#17

Disclaimer : I may sound nuts

In this case the Cobra will be a TCP client and the PC can host a TCP server application.

The NETMF can poll all the sensors on a fixed time interval or use interrupts (events) raised by sensors.

You can push sensor events and poll results into an array or have priority levels for each sensor.

You can package the sensor data into XML or a formatted string and send it to the server.

The server can parse or split the data and use as approprite.

XML sample:

<clientdata>
   <temp>1233</temp>
   <switch>1</switch>
   <ambient>233</ambient>
</clientdata>

You can use single characters for the tag to compress further.

string message sample

BOF|1233|1|233|EOF

HTH


#18

Raj

If you want to sound nuts you will have to try harder. :smiley:

As you described, another way to handle the problem is to have all calls initiated from the Cobra. The sensors on a schedule, and the events on demand.

If this works for the application it is a simpler solution.


#19

Thanks guys,

I have to go for TcpListeners on both sides because the pc will have to send commands to the Cobra for example to turn on/off a light. Will be a challenging design ::slight_smile:


#20

You probably only need a TCP listener on one side. The PC can send data on the response to the Cobra.