Re: Socket weirdness
- From: "Alan J. McFarlane" <alanjmcf@xxxxxxxxxxxxxxxxx>
- Date: Thu, 21 Sep 2006 19:42:12 +0100
In article news:eCYuc2P3GHA.4764@xxxxxxxxxxxxxxxxxxxx, Dave Sexton
wrote:
Eeeeh. I hoped to clear things up in my posting; looks like I didn't quite succeed. :-)
Here are a few questions that I still cannot answer:(Just to note firstly, doing Shutdown(Receive) alone/initially is very very very rare, Close/Shutdown(Both), or Shutdown(Send) later followed by Shutdown(Receive) is very much more common. And if a particular application/session layer protocol implied that one peer should do Shutdown(Receive) then it would not be valid for it to then have the other peer send data!)
1. If shutting down receive on a socket blocks incoming data, does
the socket respond with anything when data is actually sent from the
peer?
Anyway, if the application on one device does Shutdown(Receive) then if a packet containing data is received from the peer on that connection, then that is an not a valid packet and a packet with the RST bit set is sent clearing down the connection.
2. What actually is sent; ACK or RST, ACK and RST, nothing, or
something else?
Firstly, just to be absolutely clear, there is no such thing as an ACK packet, or a RST packet, or a SYN packet, etc. In TCP there is simply *one* type of packet, this is unlike HDLC (and its children), which carries data in 'I' frames, has ACK frames which it calls 'RR' (Receiver Ready), and lots more. :-( Unfortunately its also often those such terms that are used by our teachers...
Anyway, TCP's header is always the same format. It contains some numerical fields e.g one for the sequence number, has a set of flags: URG, ACK, PSH, RST, SYN and FIN, and finally it optionally carries some data. So (to be very correct) we can have "a packet with the ACK bit set", but no such thing as a "ACK packet". Now often in reality we generally call a packet with no data and the ACK bit set as an "ACK packet" but it can confuse...
So in the case above, a packet with the RST bit will be sent. I'm not sure whether the ACK bit will be set, I'd have to go and read the specification to be sure, and I'm not sure that it matters particularly...
3. Is the response immediate?
Err to what? :-)
The server 'immediately' sends a RST when it gets any packet that is not valid. And receiving a segment containing data is not valid where the local application has done shutdown(receive)). Of course there is time for both of those packets to cross the network.
And as we note below, a send is _not_ immediate on the application calling send (or it returning etc)...
4. Does a blocking Send wait for a response before returning to the
caller?
No. It just adds data to the buffer and returns. (Ignoring here what happens if the buffer becomes full...) The TCP protocol layer then decides when to take a segment's worth of data and send it in a packet. In general we should consider the two as independent.
5. If Send does wait for a response, why doesn't the initial call toIt doesn't. This might be where the confusion lies. :-(
Send fail when RST is received (this question is derived from how
I've understood Alan's explanation thus far)?
6. Does BeginSend wait for a response before returning to the callerNeither.
(I hope not)? Does EndSend wait for a response?
I got lost following the messages in the text below, let me know what if anything that doesn't cover. :-)
Alan
I responded to your OP because I knew how that behavior could be
explained in general terms, through simple experimentation. Now that
we gone down a more technical road I'm intrigued, yet confused.
In your test case there was no concurrent sending, so I assumed
that on a blocking send with no concurrent activity that the RST
flag would "make its way back across the network" immediately from
Alan's statements.
I think we are still talking about the same thing. RST makes it way
back to the client on an ACK. However, you may not see that ACK
until after 1 or 2 sends. I "think" tcp can send two packets
without ACK, but then must wait (correct me here if wrong) for ACK
before sending more. But eventually you will get the ACK with the
RST set and the next send/receive will fail.
That's where I'm confused. Alan's explanation does not mention ACK,
except when he stated the following early on in his response:
<snip>The flags SYN, ACK, PSH, and
URG have no part to play here.
Then eventually a packet comes from the peer, and that will
contain data, so the server responds RST: 'I can't handle that'
Yours and Alan's sound like competing explanations to me. I'm trying
to understand how this works, techincally speaking, but I'm confused
as to which explanation is correct. Or are they both correct, but
only partial answers?
Interesting that the RST made it back into the client stack butConnectionReset is returned only on every subsequent request.
I did not follow you here.
previous statements were referring to this particular statement of
Alan's. Why not just fail the initial send if the RST flag has
already been received, if in fact it is received?
I assumed that the peer was aware of the reset immediately after the
first send, as per Alan's comments above. If that is true, I'm not
sure why the first Send doesn't just fail with ConnectionReset and
not just subsequent Sends.
I guess I'll have to do some reading on my own. If ever I can
explain this phenomena I'll post my findings.
It will fail if it was received. But in our case it not (and can
not) be received until after the first send, because it is set in
the ACK of that first send. But I may already have did another Send
before first ACK is processed, so I may see it on second or third
send. If we always do the "proper" shutdown both sides, then none
of this matters and all should work fine:
1.. Finish sending data.
2.. Call shutdown() with the how parameter set to 1.
3.. Loop on recv() until it returns 0.
4.. Call closesocket().
Cheers.
--wjs
Understood, but I don't see how that applies to the OP or this
thread. I thought we were trying to address problems that have been
identified with the unorthodox, but possible, scenario for using
sockets whereby a peer attempts to shutdown receiving without a
higher-level protocol to notify its counterpart of such an
occurrence. A standardized shutdown sequence seems a bit off-topic
to me and does not address the problem at hand.
Sorry if I'm nitpicking ;)
--
Alan J. McFarlane
http://www.alanjmcf.me.uk/
Please follow-up in the newsgroup for the benefit of all.
.
- Follow-Ups:
- Re: Socket weirdness
- From: Dave Sexton
- Re: Socket weirdness
- References:
- Socket weirdness
- From: William Stacey [MVP]
- Re: Socket weirdness
- From: Dave Sexton
- Re: Socket weirdness
- From: William Stacey [MVP]
- Re: Socket weirdness
- From: Dave Sexton
- Re: Socket weirdness
- From: William Stacey [MVP]
- Re: Socket weirdness
- From: Alan J. McFarlane
- Re: Socket weirdness
- From: Dave Sexton
- Re: Socket weirdness
- From: William Stacey [MVP]
- Re: Socket weirdness
- From: Dave Sexton
- Re: Socket weirdness
- From: William Stacey [MVP]
- Re: Socket weirdness
- From: Dave Sexton
- Socket weirdness
- Prev by Date: searching byte arrays and RTFreaders
- Next by Date: Re: Exclude a project from a multi-project solution build
- Previous by thread: Re: Socket weirdness
- Next by thread: Re: Socket weirdness
- Index(es):
Relevant Pages
|