Sharing Data between apps

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

I am using Visual C# to design a system as follows:

There will be 3 computers all on the same network running identical programs
at the same time. The computers can come up in any order. The programs
(which I am writing) are supposed to share their data with one another a few
times per second. My question is how best to do this. I have very limited
knowledge of TCP/IP but have looked over the C# examples of the Client and
Server and understand them well enough. Also, would UDP be better in this
case?

My main confusion is not knowing who the Server will be or if there even has
to be a server. So how do I send and receive data (byte arrays) among them.
I am looking for any suggestions, links, components, etc.

Thank you,
Joe
 
My main confusion is not knowing who the Server will be or if there even
has
to be a server. So how do I send and receive data (byte arrays) among
them.
I am looking for any suggestions, links, components, etc.

Only you can answer that question. What are your requirements?
 
Joe said:
There will be 3 computers all on the same network running identical programs
at the same time. The computers can come up in any order. The programs
(which I am writing) are supposed to share their data with one another a few
times per second. My question is how best to do this. I have very limited
knowledge of TCP/IP but have looked over the C# examples of the Client and
Server and understand them well enough. Also, would UDP be better in this
case?

My main confusion is not knowing who the Server will be or if there even has
to be a server. So how do I send and receive data (byte arrays) among them.
I am looking for any suggestions, links, components, etc.

Take a look at .NET Remoting: Can handle peer-to-peer; does a very
nice job of handling remote method calls; lets you work at a much
higher level than sockets and byte arrays.
 
My main confusion is not knowing who the Server will be or if there even has
to be a server.

Tcp and Udp over WinSockets require a listener to receive connection requests. All framework implementations use WinSocks and
therefore require a "host". The design of the host may not actually "serve" anything, but instead just connect in a peer-to-peer
like framework where each computer is a potential host and client.

The design, as mentioned in a previous post, is up to you.

The easiest implementation would be, in my opinion, to designate a computer as a server that listens for all connections and
dispatches all bytes to all connected parties. I don't know your business requirements, but I'd imagine that this will fit better
than a peer-to-peer solution.
Also, would UDP be better in this
case?

Can your application account or handle lost packets of data? If not, then use TCP.

TcpClient and TcpListener are a good start for basic TCP/IP network applications. They use underlying Windows Sockets and a stream
(NetworkStream) to read/write data across the network.

UdpClient is the Udp version of the above two classes.
So how do I send and receive data (byte arrays) among them.

The Tcp* classes as mentioned above use a simple "NetworkStream : Stream" class that you can read/write to. It's intuitive if you
have worked with Streams of any form in the framework. So sending and receiving bytes becomes pretty easy.

A few things to consider:

1. You have to come up with your own implementation for how to receive logical groups of bytes:

A. All sends are prepended with a fixed-length byte header (1-byte command, 8-byte message length)
(I've used the above pattern and it works nicely. Of course the header could be whatever you need)
B. Logical groups of bytes are sent over "owened" connections. State-less protocols use this method. Of course, the connection
is no longer useable since the end-of-stream is determined by the connection termination.
C. End-of-message mark of some sort. For instance, at the end of all send operations, a byte-mark of a fixed-length and value
is appended. Of course, the data in the stream before the byte-mark cannot be of or contain the byte-mark. This is a questionable
approach since it is unlikely in most real-world apps that a byte-mark could be determined as always unique. It also may have a
negative effect on performance since you'd have to iterate all received bytes and match for the byte-mark.

2. You have to be able to handle network/socket errors. Unfortunately, there isn't a framework TCP implemenation that fires an
event when a socket connection is terminated, which leads into the next point...

3. You should implement some sort of graceful disconnection sequence. The first-byte in my header example could be used for this
command. (Say a Byte Enum where 1 = Greeting, 2 = Disconnect)

4. It's a pain to handle all of the "SocketException.ErrorCode"'s in a switch statement, although it should be done in order to
properly diagnos application bugs/issues. Many of the error codes can be handled in one statement, but some must be handled
differenty.

5. You must consider multi-threaded operations for performance and other reasons. This implies the coding of thread-safe methods
which adds another layer of complexity to the application.

I'm sure there's more.

Here's one more idea (that may be much less effort):

MSMQ may be a solution for you. The message queuing system ensures message delivery, even upon network failures (when the system is
back online). Larger systems using MSMQ require a designated monitoring station (i forget the exact terminology), but it may be
possible to do this peer-to-peer like for an intranet app. I'm sorry I can't provide more information about MSMQ, but research may
be worth the effort.

GL
 
Thank you all for your suggestions. I probably didn't make my question very
understandable. My concern is if I don't know the order of which computer
comes up first, how do I know which one is the server. One of you suggested
that each should be capable of being a client or server. This sounds like a
good approach but how would I go about it? I think using TCP/IP is better
than UDP because I can't afford dropping data. I will also look into MSMQ
and Remoting as suggested.

Thanks again for your help,
Joe
 
My concern is if I don't know the order of which computer
comes up first, how do I know which one is the server

You have 3 options that I can see:

1. You can designate a single computer to be the server at all times. Clients can be hard-coded to connect to a comon host (or
through configurable AppSettings). Of course, the server must always be running.

2. If you are always using the same computers to run the software, and their I.P. or host names are well-known, then you can have a
client check all "known" computers to see which one is serving at the time of initialization, and establish a connection to that.
If a server does not exist the client should become the server. To check if a computer is hosting you can just attempt to establish
a connection and set the timeout to a resonable number.

3. If the network isn't too large, it may be resonable to perform the above server check on all computers that are on the local
intranet. For larger networks you could configure a "recommended hosts" list of computer name's to be checked first. (AppSettings)

Hope it helps
 
=?Utf-8?B?Sm9lIFRob21wc29u?= said:
client or server. This sounds like a good approach but how would I go
about it? I think using TCP/IP is better than UDP because I can't
afford dropping data. I will also look into MSMQ and Remoting as

You can try Indy - its free and supports a lot more higher level functions thatn System.Net.
http://www.indyproject.org

There are some intro articles on the site as well as code project to get you started.

UDP can account for dropped data as well, but you need to build it in. Its not that difficult.


--
Chad Z. Hower (a.k.a. Kudzu) - http://www.hower.org/Kudzu/
"Programming is an art form that fights back"

Empower ASP.NET with IntraWeb
http://www.atozed.com/IntraWeb/
 
Back
Top