Re: Async Socket: How to tell when there is no more data.

Tech Tip: Click here to run a free scan for Windows Errors and optimize PC performance

From: Mainak Sarcar (MainakSarcar_at_discussions.microsoft.com)
Date: 03/17/05


Date: Thu, 17 Mar 2005 03:55:03 -0800

No David, your answer did not help me much..... Firstly the code that you
have written is a blocking type of code (synchronous). In a real world
application I can suspend the user interface in an indefinite loop till the
server sending data... Am I right. The correct approach is an Asynchronous
connection.

Your first part of the answer is correct... If the server disconnects the
socket then the client gets a received byte count of 0. But what if the
server does not disconnect the socket ... you as a client have to send some
command to the server to do that.

This is where my question arises. In the Receive Callback method how do I
get to know how much data to read. Data may be in a few bytes or it may be in
MBs..

Regards,
Mainak

"David Levine" wrote:

> When a sender closes the socket the receiver is notified when the received
> byte count is zero - this indicates that a graceful shutdown of the socket
> was initiated from the other end, which means that you should close the
> socket on your end to complete the shutdown. This is NOT the same as reading
> the value of the Available property. Perhaps this is what the sample code
> was intending.
>
> I use a two-phase method for determining how much data to read. The 1st
> phase sends a fixed size header block, with fields like this...
>
> struct header
> {
> int version; // and other header stuff to detect options and/or corruption
> in the sender
> int size; // size of the variable length portion of the data
> }
>
> You can put anything you like in the header but you must at least put the
> size there. Once you've read in the fixed size header, read the length of
> the data that follows. An advantage of this mechanism is that you always
> know when you've read in the entire message without needing special EOF or
> formatting characters. Also, if you ever receive bad values in the header
> you know that the sender has become corrupted and you should terminate the
> connection.
>
> Your code then implements a state machine, either at step 1 (reading header)
> or step 2 (reading data). It's quite simple and effective.
>
> Also, if you are using TCP then you should know that your call to receive
> may not get all the data in one call...you need a buffering scheme that
> reads data and adds it to a temporary buffer until the entire message has
> been received by your application. In other words, the code you posted may
> get partial strings because message boundaries are not respected. I use code
> like this (not aysnc, I use blocking calls and separate threads per
> client)...
>
> public static void Receive(Socket s,byte[] buffer)
> {
> int total = 0;
> int size = buffer.Length;
> int dataLeft = size;
> int received = 0;
> int loops = 0;
> while ( total < size )
> {
> received = s.Receive(buffer,total,dataLeft,SocketFlags.None);
> if ( received == 0 )
> return; // socket was closed by client - disconnect.
> total += received;
> dataLeft -= received;
> loops++; // diagnostics only - this can be greater then 1
> }
> } // Receive
>
> If you are using UDP then message boundaries are respected and the above
> does not apply, but I don't think that is the case because then you would
> not even need framing characters and you would not need to "know" the size
> of the incoming message.
>
> Hope this helps,
>
>
> "Mainak Sarcar" <MainakSarcar@discussions.microsoft.com> wrote in message
> news:784583CD-33D8-4E2C-B376-07ADE0C0152C@microsoft.com...
> > Very Correct... But using a terminator like that is ONLY possible if you
> > have control over what the server is sending..
> > What if I am using real world servers like POP3 or SMTP which have no
> > terminators to denote that all data has been received... I have tried
> > using
> > socket.Available property but it is unreliable... because at times it
> > gives 0
> > bytes available, but if you wait for 1-2 secs and check the property again
> > ... it has some bytes available for reading.. How would you get to know
> > when
> > to stop reading and when to call "beginReceive" method again ????
> >
> > I found this crappy code from MSDN.. which is ABSOLUTELY WRONG... the
> > program never reaches the "else" part of the code...while the socket is
> > connected.
> > private static void ReceiveCallback( IAsyncResult ar )
> > {
> > try
> > {
> > StateObject state = (StateObject) ar.AsyncState;
> > Socket client = state.workSocket;
> > int bytesRead = client.EndReceive(ar);
> >
> > if (bytesRead > 0)
> > {
> > //Get more data....
> >
> > state.sb.Append(Encoding.ASCII.GetString(state.buffer,0,bytesRead));
> > client.BeginReceive(state.buffer,0,StateObject.BufferSize,0,
> > new
> > AsyncCallback(ReceiveCallback), state);
> > }
> > else
> > {
> > // All the data has arrived; put it in response.
> > if (state.sb.Length > 1)
> > {
> > response = state.sb.ToString();
> > }
> > // Signal that all bytes have been received.
> > receiveDone.Set();
> > }
> > } catch (Exception e) {
> > Console.WriteLine(e.ToString());
> > }
> > }
> >



Relevant Pages

  • [NT] Port80 Software ServerMask Inconsistencies
    ... The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com ... IIS servers by obfuscating header fields within HTTP responses: ... "ServerMask 2.0 removes or modifies unnecessary response data. ... provide reliable clues to the server being Microsoft IIS. ...
    (Securiteam)
  • Re: minimal httpd response
    ... RST, abortively closing the connection. ... The responsibilities of an HTTP/1.1 proxy, and of an HTTP/1.1 server ... user agent, without a proxy, first, and then try to deal ... Connection header; with a Content-length header; or with the chunked ...
    (comp.programming)
  • Re: I want my MOM
    ... >> 5) Require that the header MUST have the content-length ... >> again slam the server with never ending data until it dies. ... server to have a reason to boot bad clients. ... Another thing a pre-sized protocol does is make it much harder to have ...
    (comp.lang.ruby)
  • Re: MimeOLE V6.00.2900.2180 creates incorrect X- header
    ... from Server, such as move to another folder, does ... engine loops when it encounters the defective empty header when it ... the POP3 server sends a period on a line by ... The search for the final header loops because of the malformed EOM ...
    (microsoft.public.windows.inetexplorer.ie6_outlookexpress)
  • Re: Its driving me crazy!
    ... Here's a sample list of ISPs ... The first header is a "Received" header. ... You can trust most of what this header tells you. ... The server at that address _claimed_ that it was ...
    (microsoft.public.security.virus)