Asynchronous multi-direction server-client communication over the same open socket? - c#

I have a client-server app where the client is on a Windows Mobile 6 device, written in C++ and the server is on full Windows and written in C#.
Originally, I only needed it to send messages from the client to the server, with the server only ever sending back an acknowledgement that it received the message. Now, I would like to update it so that the server can actually send a message to the client to request data. As I currently have it set up so the client is only in receive mode after it sends data to the server, this doesn't allow for the server to send a request at any time. I would have to wait for client data. My first thought would be to create another thread on the client with a separate open socket, listening for server requests...just like the server already has in respect the client. Is there a way, within the same thread and using the same socket, to all the server to send requests at any time?
Can you use something to the effect of WaitForMultipleObjects() and pass it a receive buffer and an event that tells it there is data to be sent?

When I needed to write an application with a client-server model where the clients could leave and enter whenever they want, (I assume that's also the case for your application as you use mobile devices) I made sure that the clients send an online message to the server, indicating they were connected and ready to do whatever they needed doing.
at that time the server could send messages back to the client trough the same open connection.
Also, but I don't know if that is applicable for you, I had some sort of heartbeat the clients sent to the server, letting it know it was still online. That way the server knows when a client was forcibly disconnected from the network and it could mark that client back as offline.

Using asynchronous communication is totally possible in single thread!
There is a common design pattern in network software development called the reactor pattern (look at this book). Some well known network library provides an implementation of this pattern (look at ACE).
Briefly, the reactor is an object, you register all your sockets inside, and you wait for something. If something happened (new data arrived, connection close...) the reactor will notify you. And of course, you can use only one socket to send and received data asynchronously.

I'm not clear on whether or not you're wanting to add the asynchronous bits to the server in C# or the client in C++.
If you're talking about doing this in C++, desktop Windows platforms can do socket I/O asynchronously through the API's that use overlapped I/O. For sockets, WSASend, WSARecv both allow async I/O (read the documentation on their LPOVERLAPPED parameters, which you can populate with events that get set when the I/O completes).
I don't know if Windows Mobile platforms support these functions, so you might have to do some additional digging.

Check out asio. It is a cross compatable c++ library for asyncronous IO. I am not sure if this would be useful for the server ( I have never tried to link a standard c++ DLL to a c# project) but for the client it would be useful.
We use it with our application, and it solved most of our IO concurrency problems.

Related

Synchronizing Client and Server interaction

So I am making this tcp program which simply sends and receives information between a client and a server.
My setup works as follows:
1)Server starts listening
2)Client sends "hello" command as well as a username/password
3)Server sends either "correctpass" or "wrongpass"
4)Client starts sending massive amounts of data in 50kb intervals
5)Server receives and stores this data as it comes
My question is: Is there something I should do to make sure that client doesn't send data when the server isn't listening? Forexample, should there be a command sent from server saying that it successfully got the data? I am just wondering this because I can't have the data come not in order.
I am receiving via tcp and I understand that TCP should send all the data to the server, but my problem is that the server might not be reading at the time that it is sent to it.
My other question is: Is TCP a good protocol for sending lots of small data (adding up to alot) through the internet? Is this how dropbox and other sync utilities communicate with their servers?
Edit:
I am currently using C# and networkstream to communicate
Thanks,
Rohit
First think that you need to do it's to read about data communications protocols and standarts thats already invented.
Includes OSI/ISO http://en.wikipedia.org/wiki/OSI_model
That help you to understand levels of tcp and udp, http, rest and etc.
Learn about technologies designed for interaction and communication like WCF.
But dont forget to play with your custom protocol it gives you experiences and representation how data comunications work and why and when use different protocols and technologies.
To work around data transfer collision you can use reqest/answer organization of communication.
But with WCF service you can do data transfer easyly. Without a lot of coding and misatkes.
Tcp is good to send data and be enshured from data coruption.
my problem is that the server might not be reading at the time that it
is sent to it.
The problem you are worrying about doesn't really exist. If the server doesn't have the connection open you will get a 'connection reset'. If the server isn't reading as fast as you are writing your writes will block in blocking mode, or return a retry indication in non-blocking mode.

Multithreaded server, send data independently?

I'm trying to build a simple multithreaded tcp server. The client connects and sends data to server, the server responds and waits for data again. The problem is I need the server to listen for incoming data in separate thread and be able to send command to client any time (for example to notify about new update). As far as I understood, when ever client sends data to server, if server doesn't respond with any data, client app doesn't let me send more data, server simply doesn't receive them. If I send data ether way around, does the data need to be 'acknowledged' for tcpclient?
Here's the source for the server: http://csharp.net-informations.com/communications/files/print/csharp-multi-threaded-server-socket_print.htm
How can I make the server send command to a client in separate thread outside the "DoChat" functions loop? or do I have to handle everything in that thread? Do I have to respond to each request client sends me? Thanks!
The problem is I need the server to listen for incoming data in separate thread
No, there is an async API. You can polll a list of threads to see which ahve new data waiting, obcviously to be done froa worker thread.
As far as I understood, when ever client sends data to server, if server doesn't respond with any
data, client app doesn't let me send more data, server simply doesn't receive them.
That is a lot more crap programming than the way sockets work. Sockets are totally ok with streaming ata in sending and receiving direction att the same time.
How can I make the server send command to a client in separate thread outside the "DoChat"
functions
Wel, me diong your job costs money.
BUT: The example is retarded. As in- totally anti pattern. One thread per client? You will run into memroy problems and perforamnce problems once 1000+ clients connect. You get tons of context switches.
Second, the client is not async because it is not written so. Mayy I suggest giong to the documentation, reading up on sockts an trying to build that yourself? THEN come back with questions that show more than "i just try to copy paste".
With proper programming this is totally normal. I have a similar application in development, sending data lall the time to the client and getting commands from the client to modify the data stream. Works liek a charm.
If I send data ether way around, does the data need to be 'acknowledged' for tcpclient?
Yes and no. No, not for TCP - TCP does it'Äs wn handshake under the hoods. Yes, if your protocol decides it has to, which is a programmer level design decision. It may or may not be necesssary, depending on the content of the data. Sometimes the acknowledgement provides more information (timestamp server side, tracking numer) and is not pure ly there for "I got it".

CF app two way communications with server

Users in field with PDA's will generate messages and send to the server; users at the server end will generate messages which need to be sent to the PDA.
Messages are between the app and server code; not 100% user entered data. Ie, we'll capture some data in a form, add GPS location, time date and such and send that to the server.
Server may send us messages like updates to database records used in the PDA app, messages for the user etc.
For messages from the PDA to server, that's easy. PDA initiates call to server and passes data. Presently using web services at the server end and "add new web reference" and associated code on the PDA.
I'm coming unstuck trying to get messages from the the server to the PDA in a timely fashion. In some instances receiving the message quickly is important.
If the server had a message for a particular PDA, it would be great for the PDA to receive that within a few seconds of it being available. So polling once a minute is out; polling once a second will generate a lot of traffic and, maybe draim the PDA battery some ?
This post is the same question as mine and suggests http long polling:
Windows Mobile 6.0/6.5 - Push Notification
I've looked into WCF callbacks and they appear to be exactly what I want however, unavailable for compact framework.
This next post isn't for CF but raises issues of service availability:
To poll or not to poll (in a web services context)
In my context i'll have 500-700 devices wanting to communicate with a small number of web services (between 2-5).
That's a lot of long poll requests to keep open.
Is sockets the way to go ? Again that's a lot of connections.
I've also read about methods using exchange or gmail; i'm really hesitant to go down those paths.
Most of the posts i've found here and in google are a few years old; something may have come up since then ?
What's the best way to handle 500-700 PDA CF devices wanting near-instant communication from a server, whilst maintaing battery life ? Tall request i'm sure.
Socket communication seems like the easiest approach. You say you're using webservices for client-server comms, and that is essentially done behind the scenes by the server (webservice) opening a socket and listening for packets arriving, then responding to those packets.
You want to take the same approach in reverse, so each client opens a socket on its machine and waits for traffic to arrive. The client will basically need to poll its own socket (which doesnt incur any network traffic). Client will also need to communicate its ip address and socket to the server so that when the server needs to communicate back to the client it has a means of reaching it. The server will then use socket based comms (as opposed to webservices) to send messages out as required. Server can just open a socket, send message, then close socket again. No need to have lots of permanently open sockets.
There are potential catches though if the client is roaming around and hopping between networks. If this is the case then its likely that the ip address will be changing (and client will need to open a new socket and pass the new ip address/socket info to the server). It also increases the chances that the server will fail to communicate with the client.
Sounds like an interesting project. Good luck!
Ages ago, the CF team built an application called the "Lunch Launcher" which was based on WCF store-and-forward messaging. David Kline did a nice series on it (here the last one, which has a TOC for all earlier articles).
There's an on-demand Webcast on MSDN given by Jim Wilson that gives an outline of store-and-forward and the code from that webcast is available here.
This might do what you want, though it got some dependencies (e.g. Exchange) and some inherent limitations (e.g. no built-in delivery confirmation).
Ok, further looking and I may be closer to what I want; which I think i a form of http long poll anyway.
This article here - http://www.codeproject.com/KB/IP/socketsincsharp.aspx - shows how to have a listener on a socket. So I do this on the server side.
Client side then opens a socket to the server at this port; sends it's device ID.
Server code first checks to see if there is a response for that device. If there is, it responds.
If not, it either polls itself or subscribes to some event; then returns when it's got data.
I could put in place time out code on the server side if needed.
Blocking on the client end i'm not worried about because it's a background thread and no data is the same as blocking at the app level; as to CPU & batter life, not sure.
I know what i've written is fairly broad, but is this a strategy worth exploring ?

Asynchronous UDP Server for multiple clients in C#

I have a task to do and I am new to networking, so like to discuss before coding down. I have to write down server side UDP application. Server listens for connection request from many clients (could be 100 or more). When it receives it then it does some handshake, by sending acknowledge back and forth couple of times, with the client application to know its identity. When connection is established it receives different types of data from the clients which it does processing and put in the sql database and send acknowledge back to client. Periodically send command to clients for specific information it requires.
I am using C# with Visual Studio 2005. Should I use multi threading? threadpool? Asynchronous or sync UDP Server?
Thanks in advance.
Are you sure what you want is a UDP server? Terms such as "connections", "handshakes" are all TCP related.
I would use asynchronous methods in both the server and the client. It will complicate things, especially in the client.
The reason is that you write that the server will send stuff to the client sometimes. This makes a simple request/reply type of communication impossible (the client calls Send and then uses Receive until a proper answer have been received).
If you can scrap that requirement I would use synchronous clients (do some polling instead) which would make stuff a lot easier for you to understand.
If you have .Net 3.5, why don't you create a WCF service instead? It supports TCP and callbacks (server can call stuff in the client).

Driving events across custom TCP Long-Polling server

I’m trying to write a custom TCP based long polling server that will serve as a go-between for other TCP connections that require more persistence than a mobile phone can provide.
The way I’m trying to do it is writing an asynchronous TCP server in C# and a matching TCP Client also written in C#.
The way that long polling works (as far as I understand it) is that you open a TCP connection to a server, and the server Halts before sending data back across the socket. You find a Heartbeat interval that works on a mobile phone network (I’ve heard that around 8 minutes works?) and you send an empty packet if there is no updated data.
This is where my trouble comes in. I can’t figure out how to “link” my client’s request for data with an event handler running on the server…
The flow should be something like this (“client” is on a phone):
User starts my application
Client sends a request to be notified if data has changed
Server “links” (registers) client’s socket object into an “Event handler” that is called by the server’s other TCP connections that I talked about!
Event
o If it is triggered (new data has arrived), Send the data to the client
o If it isn’t triggered (no new data), Send an “EmptyChanges” packet to client
Client receives data on the phone and processes it (calls an event handler based on what type of packet it received and passes the “data” it got from the server to it)
Client sends a request to be notified if data has changed
So, my problem is that I can’t think of a design that will accomplish what I want it to do. The problem is that I don’t know HOW to do #3. How do I “Link” one event handler from another? And these are almost guaranteed to be running on different threads!
So, my application would look something like this (all psuedocode):
Class AppClass
{
Main()
List<Client> clients;
List<DataServers> dataServers;
DataReceivedFromServer(Data stuff)
{
}
MessageReceivedFromPhone(PhoneMessage pm, object sender)
{
//Loop here until HeartBeat interval reached
Int totalTime = 0;
While(totalTime < HEARTBEAT_INTERVAL)
{
If( ) // If we have received data from the server, and the client WANTED that data, send it now
{
}
}
}
}
Kind of? I want it to be event driven, but I'm having the damndest time figuring out how to drive the application with a PUSH driven style vs. what I'm "used" to of Polling.
Please, be kind as I might be doing something overly complicated and stupid because this is my first real attempt at using Socket programming (never needed it) and it's especially hard due to the nature of Cell phones being on transient networks and my server needing to maintain the location of these phones with an OPEN TCP connection.
Server platform: Windows
Server language: C#
Test Client platform: Windows
Test Client language: C#
Target Client platform: Windows Mobile 6.5, iPhone, Android (clients will be written separately)
Target client language: C#, Obj-C or MonoTouch, Java
Just anyone wondering this, I trashed the idea of writing a custom TCP server to manage my connections. There was so much overhead in doing that, I'd basically be replicating writing my own HTTP server, so instead of doing that, I went with the Web Tornado framework in Python as my server and am writing the back end services to communicate through HTTP requests in Web Tornado.
Instead of using Long polling at all, I'm going to use SMS for push notifications. I believe all of the major phone platforms implement something similar to an SMS Interceptor that you write... if an SMS of a certain format comes through, it will run your custom code. This allows me to remove the requirements of using consistent open connections (other than for live chat, which will use a comet style Long poll, but the connection can only remain open if active for about 5 minutes.)
Basically, the Web Tornado framework is serving as an Enterprise bus in my architecture.

Categories