Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / C# / March 2008

Tip: Looking for answers? Try searching our database.

writing an async client (sockets/async/thread)

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
asharda@woh.rr.com - 12 Feb 2008 20:04 GMT
Hello,

My experience with socket-programming is close to zero.

I am looking for some kind of template which describes as to how the
async-client (which can handle multiple responses from a server) can
be written (i saw few examples on the net, but in those examples, the
client execution terminates after sending/receiving response).

Basically, the client should:
- Connect to the server (at specific IP/port)
- Respond to any message it gets from server (once connected to the
server, client should be continuously running, waiting for messages
and and call respond appropriately).

So, this way, if there are multiple messages that server is sending to
client at the same time, client should be able to handle it (so this
client will be kind-of behaving like a server in the sense that each
time it gets a connection, it assigns it to a worker-process and then
keeps listening for other messages).

Is this feasible? if yes, then can you give some examples?

Platform: XP, vs2005 OR vs2008

Thanks.
Peter Duniho - 12 Feb 2008 20:38 GMT
> Hello,
>
[quoted text clipped - 4 lines]
> be written (i saw few examples on the net, but in those examples, the
> client execution terminates after sending/receiving response).

The difference between an application that terminates after sending and  
receiving a response and one that doesn't is generally a trivial matter.  
The complicated part is in the sending and receiving.  Getting a program  
to not exit is usually just a matter of using a loop, or having everything  
execute in the context of a GUI where the network i/o thread(s) has  
nothing to do with the application lifetime at all.

> Basically, the client should:
> - Connect to the server (at specific IP/port)
> - Respond to any message it gets from server (once connected to the
> server, client should be continuously running, waiting for messages
> and and call respond appropriately).

Depending on your preference, the Socket or "client" classes (UdpClient,  
TcpClient) are likely to provide what you need.

> So, this way, if there are multiple messages that server is sending to
> client at the same time, client should be able to handle it (so this
[quoted text clipped - 3 lines]
>
> Is this feasible? if yes, then can you give some examples?

MSDN has a number of code samples, some better than others.  I'm not aware  
of any specific ones that are better, though they may exist.  The basic  
idea is not complicated though.  In the context of .NET, you have two main  
approaches: one thread per connection, or using the asynchronous API.  
IMHO the latter is better and in fact can be clearer in code as well.  But  
depending on your experience level, one thread per connection might be  
easier to grasp initially.

You should look at the MSDN documentation for the Socket, TcpClient, and  
UdpClient classes.  They provide a variety of samples and explanations for  
how one might use the classes.  In addition, if you know very little about  
socket programming, IMHO you should start with the simplest samples:

    1) Simple UDP client/server setup where you have two endpoints, each  
only ever sending a single message then waiting for a reply.

    2) Simple TCP client/server setup, similar to sample #1.

You should also review the Winsock FAQ:
http://tangentsoft.net/wskfaq/

If you're going to use TCP, pay particular attention to these pages, as  
they cover one of the most common mistakes people new to network  
programming make:
http://tangentsoft.net/wskfaq/articles/effective-tcp.html
http://tangentsoft.net/wskfaq/intermediate.html#tcp

Pete
Jeroen Mostert - 12 Feb 2008 20:51 GMT
<snip>
> You should also review the Winsock FAQ:
> http://tangentsoft.net/wskfaq/
[quoted text clipped - 4 lines]
> http://tangentsoft.net/wskfaq/articles/effective-tcp.html
> http://tangentsoft.net/wskfaq/intermediate.html#tcp

I'm going to quote this just to highlight it again, because many people are
not only unaware of these issues, but often think that using .NET means they
don't have to know these things -- because Winsock is "lower level". In
reality, the .NET classes are relatively thin wrappers around the core
Winsock functionality (and they certainly will not change the essential
nature of TCP/IP), and you cannot afford not to know anything about it.

A common mistake I've seen in our company's codebase, for example, is people
rudely slamming connections shut because they don't know how to do proper
shutdowns. This is not a big problem as long as your applications are
frolicking around on a LAN, but once they hit the Internet, it can
complicate things quickly.

Signature

J.

asharda@woh.rr.com - 12 Feb 2008 22:08 GMT
> <snip>> You should also review the Winsock FAQ:
> >http://tangentsoft.net/wskfaq/
[quoted text clipped - 20 lines]
> --
> J.

Thanks J.

- I wrote a quick/dirty synchronous client as a basic POC. It appears
to communicate with Server and exits out.
- I am thinking of going the async (delegate/callback) way and see how
it goes. I am hoping that a 'loop' won't eat up on cpu (i tried doing
a loop with sync and cpu-usage on my xp went to around 50%).

I will go through the links you have provided.
R
Peter Duniho - 12 Feb 2008 22:33 GMT
> [...]
> - I wrote a quick/dirty synchronous client as a basic POC. It appears
> to communicate with Server and exits out.
> - I am thinking of going the async (delegate/callback) way and see how
> it goes. I am hoping that a 'loop' won't eat up on cpu (i tried doing
> a loop with sync and cpu-usage on my xp went to around 50%).

Sounds like polling.  Don't poll.  If you have a loop in a thread, it  
should either be doing useful work, or it should be waiting for some other  
thread to tell it to do something.  You should never have a loop that just  
sits there looping.

Pete
asharda@woh.rr.com - 14 Feb 2008 13:54 GMT
On Feb 12, 5:33 pm, "Peter Duniho" <NpOeStPe...@nnowslpianmk.com>
wrote:
> > [...]
> > - I wrote a quick/dirty synchronous client as a basic POC. It appears
[quoted text clipped - 9 lines]
>
> Pete

Ok, i did 'some form' of async programming (well, not even sure if it
can be called async-programming). My cpu-usage is back to normal (0% -
1%). But the occasional problem i am seeing is when server sends two
messages at the same time.....in some instances client gets only one
message (i tested the server-end with another client-async-program
that somebody else had written and there is no such issue there....so,
server-end appears to be working ok).

Here is a high-level steps of what i wrote (console app):

- Connect() //server-IP/port#
- SendMessageToServer()
- ReadDataFromServer()
    {
           ReadComplete = new AutoResetEvent(false);
           IAsyncResult asyncRes = stream.BeginRead(bufferName,
0,bufferName.Length,new AsyncCallBack(ReadAsyncData),stream);
           ReadComplete.WaitOne();
   }

- ReadAsyncData(IAsyncResult asyncRes)
   {
      int bytesRd = ns.EndRead(asyncRes);
      fullData =
String.Concat(fullData,Encoding.ASCII.GetString(bufferName,0,bytesRd);

      if (bytesRd > 0)
      {
         ProcessData and send message to Server if need be.....
         stream.BeginRead(bufferName,0,bufferName.Length,new
AsyncCallBack(ReadAsyncData),stream);
      }
      else
         ReadComplete.Set();
   }

For clarity-purposes, i have shown the relevant data above.

I am not sure if this is a truly an asnc program or an attempt for
async-program but has bits/pieces of sync-programming...

Any suggestions/advice on possible changes and why i am seeing the
above mentioned problem?

Thanks.
RS
Peter Duniho - 14 Feb 2008 19:20 GMT
> Here is a high-level steps of what i wrote (console app):
>
[quoted text clipped - 7 lines]
>             ReadComplete.WaitOne();
>     }

So, you want this part to just sit and wait until the stream is closed.  
Right?

> - ReadAsyncData(IAsyncResult asyncRes)
>     {
>        int bytesRd = ns.EndRead(asyncRes);
>        fullData =
> String.Concat(fullData,Encoding.ASCII.GetString(bufferName,0,bytesRd);

Shouldn't you wait until you've checked "bytesRd" before bother to try to  
decode the data?  I don't think you'll get an error here, but it still  
seems like bad form.

>        if (bytesRd > 0)
>        {
>           ProcessData and send message to Server if need be.....

What does "ProcessData" do?  Are you prepared to receive a partial  
message?  Are you prepared to receive two messages combined in the same  
receive?  If the answer to either of those is "no", you have a bug.

>           stream.BeginRead(bufferName,0,bufferName.Length,new
> AsyncCallBack(ReadAsyncData),stream);
[quoted text clipped - 7 lines]
> I am not sure if this is a truly an asnc program or an attempt for
> async-program but has bits/pieces of sync-programming...

For a console application that is specifically supposed to connect to a  
single server a single time and exit when that connection has been closed,  
it looks fine to me.  YMMV.  :)

> Any suggestions/advice on possible changes and why i am seeing the
> above mentioned problem?

Well, you didn't post a complete sample, so it's not really possible to  
answer specific questions.  However, I refer you to the links I mentioned  
before.  Based on the vague description of the behavior you're seeing, it  
_could_ be that you are making invalid assumptions about the grouping of  
data sent to you.

Pete
asharda@woh.rr.com - 17 Mar 2008 20:55 GMT
Hello guys,

Finally, able to get back on this.

Pete,
- Yep, i want that part to wait until the stream is closed.
- You are correct, no point in reading bytes until bytesRd has been
checked.
- You mentioned about 'Are you ready to receive two messages combined
in the same receive?'. Can you elaborate on this? Could this be the
cause of the problem i discussed above (occasionally, when the server
tries to send two messages simultaneously, only one gets captured/
processed and not the other one)? Is there a way to find out if
complete message has been received (before we proceed with
processing?)

If more information is needed, I can try and send code-snippets (I had
assumed that the code provided in the earlier postings would be
sufficient to help resolve/pin-point the issue).

On Feb 14, 3:20 pm, "Peter Duniho" <NpOeStPe...@nnowslpianmk.com>
wrote:
> > Here is a high-level steps of what i wrote (console app):
>
[quoted text clipped - 55 lines]
>
> Pete
Peter Duniho - 17 Mar 2008 23:04 GMT
> [...]
> - You mentioned about 'Are you ready to receive two messages combined
> in the same receive?'. Can you elaborate on this?

TCP is a stream of bytes, without any grouping imposed on it.  No matter  
what grouping you (or whatever transmitter) used when you sent the bytes  
out, when the bytes arrive they may have any other arbitrary grouping.  
The bytes are guaranteed to be in the same order in which they were sent,  
but there is no other guarantee.

This means, for example, if the sender sends two groups of bytes in short  
succession, those two groups may be combined into a single group and sent  
together.  It is up to the receiver to correctly determine where the first  
group ends and the second group begins.  If the receiver is assuming that  
it will only receive one group at a time, then it could easily wind up  
receiving both groups but ignore the second because it only expected the  
first.

This bug will manifest itself as appearing to simply "miss" the second  
group of bytes.

Note that the above is just one example.  Again, the actual grouping of  
bytes when you receive can be _anything_.  You could receive just one byte  
at a time, you could receive a few bytes, then all of the rest of them,  
you could receive half of the first group, then the second half plus the  
first half of the second group, then the second half of the second group,  
or any other combination you can imagine.

It is up to you to write the code so that you take bytes that are streamed  
to you, and organize them as you need them to be.

> Could this be the
> cause of the problem i discussed above (occasionally, when the server
> tries to send two messages simultaneously, only one gets captured/
> processed and not the other one)?

Yes, it could easily create that situation.  That's why I pointed it out  
as a potential problem.

> Is there a way to find out if
> complete message has been received (before we proceed with
> processing?)

If there's not, then you have a flaw in your application protocol.  Your  
application protocol needs to be defined in such a way that the receiver  
can determine where the message boundaries exist in the stream of data  
that TCP provides, as TCP will not itself do this for you.

So, while I can't answer the question you asked (you haven't offered  
enough details regarding your application protocol), I can at least tell  
you that if your application protocol is correct, the answer is "yes".  If  
the answer is "no", then you need to fix the protocol.

Pete

Rate this thread:







Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.