Subject: Re: query: using two write() calls in succession

From: der Mouse <[email-masked]>
Date: Mon, 26 Mar 2001 10:12:26 -0500 (EST)

> 1. The second write() call in succession  does not fail. However, if I =
> sleep for 1 second
> in between the two writes, the second write() call fails and returns er=
> rno with ECONNRESET.

This doesn't surprise me.  Without the delay, the first write()
generates an outgoing segment, sure, which draws an RST segment in
response from the peer - but the second write() occurs well before the
RST is received by the sending host.  Even on a fast LAN, this usually
takes at least a millisecond or so, and it's the rare machine that's so
slow as to be unable to do back-to-back writes in less than that.

The rest of your questions I can't help with.

					der Mouse

			       [email-masked]
		     7D C8 61 52 5D E7 2D 39  4E F1 31 3E E8 B3 27 4B

---

From: [email-masked]
Date: Mon, 26 Mar 2001 18:15:53 +0200

Please find my comments appended.

Regards,
Rajiv Chakravorty

>slow as to be unable to do back-to-back writes in less than that.

Yes, this was my first guess. But it doesnt happen this way. Actually,
I think I am receiving the RST well before I perform the second write. 
Here's the tcpdump output when the code is run on (Linux 2.2.16) without 1 sec 
sleep between two writes (sorry for not enabling the relative time option):

client: wsasa3005
www/server: asaehv.ce.philips.com

17:31:17.185481 eth0 > wsasa3005.asa-ehv.ce.philips.com.1181 > asaehv.ce.philips.com.www: S 1292046262:1292046262(0) win 32120 <mss 1460,sackOK,timestamp 104441703 0,nop,wscale 0> (DF)
17:31:17.185986 eth0 < asaehv.ce.philips.com.www > wsasa3005.asa-ehv.ce.philips.com.1181: S 3010001540:3010001540(0) ack 1292046263 win 8760 <mss 1460> (DF)
17:31:17.186090 eth0 > wsasa3005.asa-ehv.ce.philips.com.1181 > asaehv.ce.philips.com.www: . 1:1(0) ack 1 win 32120 (DF)
17:31:17.186250 eth0 > wsasa3005.asa-ehv.ce.philips.com.1181 > asaehv.ce.philips.com.www: P 1:2(1) ack 1 win 32120 (DF)
17:31:17.233839 eth0 < asaehv.ce.philips.com.www > wsasa3005.asa-ehv.ce.philips.com.1181: . 1:1(0) ack 2 win 8760 (DF)
17:31:17.233891 eth0 > wsasa3005.asa-ehv.ce.philips.com.1181 > asaehv.ce.philips.com.www: P 2:34(32) ack 1 win 32120 (DF)
17:31:17.247262 eth0 < asaehv.ce.philips.com.www > wsasa3005.asa-ehv.ce.philips.com.1181: P 1:1461(1460) ack 34 win 8760 (DF)
17:31:17.247337 eth0 > wsasa3005.asa-ehv.ce.philips.com.1181 > asaehv.ce.philips.com.www: . 34:34(0) ack 1461 win 30660 (DF)
17:31:17.249255 eth0 < asaehv.ce.philips.com.www > wsasa3005.asa-ehv.ce.philips.com.1181: . 1461:2921(1460) ack 34 win 8760 (DF)
17:31:17.250033 eth0 > wsasa3005.asa-ehv.ce.philips.com.1181 > asaehv.ce.philips.com.www: . 34:34(0) ack 2921 win 30660 (DF)
17:31:17.250391 eth0 < asaehv.ce.philips.com.www > wsasa3005.asa-ehv.ce.philips.com.1181: P 2921:4243(1322) ack 34 win 8760 (DF)
17:31:17.253254 eth0 < asaehv.ce.philips.com.www > wsasa3005.asa-ehv.ce.philips.com.1181: . 4243:5703(1460) ack 34 win 8760 (DF)
17:31:17.254483 eth0 < asaehv.ce.philips.com.www > wsasa3005.asa-ehv.ce.philips.com.1181: . 5703:7163(1460) ack 34 win 8760 (DF)
17:31:17.254546 eth0 > wsasa3005.asa-ehv.ce.philips.com.1181 > asaehv.ce.philips.com.www: . 34:34(0) ack 7163 win 27740 (DF)
17:31:17.256139 eth0 < asaehv.ce.philips.com.www > wsasa3005.asa-ehv.ce.philips.com.1181: . 7163:8347(1184) ack 34 win 8760 (DF)
17:31:17.257379 eth0 < asaehv.ce.philips.com.www > wsasa3005.asa-ehv.ce.philips.com.1181: P 8347:9807(1460) ack 34 win 8760 (DF)
17:31:17.258604 eth0 < asaehv.ce.philips.com.www > wsasa3005.asa-ehv.ce.philips.com.1181: P 9807:11267(1460) ack 34 win 8760 (DF)
17:31:17.258670 eth0 > wsasa3005.asa-ehv.ce.philips.com.1181 > asaehv.ce.philips.com.www: . 34:34(0) ack 11267 win 26280 (DF)
17:31:17.259607 eth0 < asaehv.ce.philips.com.www > wsasa3005.asa-ehv.ce.philips.com.1181: P 11267:12451(1184) ack 34 win 8760 (DF)
17:31:17.260026 eth0 > wsasa3005.asa-ehv.ce.philips.com.1181 > asaehv.ce.philips.com.www: . 34:34(0) ack 12451 win 25096 (DF)
17:31:17.261449 eth0 < asaehv.ce.philips.com.www > wsasa3005.asa-ehv.ce.philips.com.1181: . 12451:13911(1460) ack 34 win 8760 (DF)
17:31:17.262677 eth0 < asaehv.ce.philips.com.www > wsasa3005.asa-ehv.ce.philips.com.1181: . 13911:15371(1460) ack 34 win 8760 (DF)
17:31:17.262741 eth0 > wsasa3005.asa-ehv.ce.philips.com.1181 > asaehv.ce.philips.com.www: . 34:34(0) ack 15371 win 23360 (DF)
17:31:17.263905 eth0 < asaehv.ce.philips.com.www > wsasa3005.asa-ehv.ce.philips.com.1181: . 15371:16831(1460) ack 34 win 8760 (DF)
17:31:17.264875 eth0 < asaehv.ce.philips.com.www > wsasa3005.asa-ehv.ce.philips.com.1181: . 16831:17865(1034) ack 34 win 8760 (DF)
17:31:17.266120 eth0 < asaehv.ce.philips.com.www > wsasa3005.asa-ehv.ce.philips.com.1181: . 17865:19325(1460) ack 34 win 8760 (DF)
17:31:17.266203 eth0 > wsasa3005.asa-ehv.ce.philips.com.1181 > asaehv.ce.philips.com.www: . 34:34(0) ack 19325 win 21900 (DF)
17:31:17.267351 eth0 < asaehv.ce.philips.com.www > wsasa3005.asa-ehv.ce.philips.com.1181: P 19325:20785(1460) ack 34 win 8760 (DF)
17:31:17.268485 eth0 < asaehv.ce.philips.com.www > wsasa3005.asa-ehv.ce.philips.com.1181: P 20785:21835(1050) ack 34 win 8760 (DF)
17:31:17.270034 eth0 > wsasa3005.asa-ehv.ce.philips.com.1181 > asaehv.ce.philips.com.www: . 34:34(0) ack 21835 win 19390 (DF)
17:31:33.748842 eth0 < asaehv.ce.philips.com.www > wsasa3005.asa-ehv.ce.philips.com.1181: F 21835:21835(0) ack 34 win 8760 (DF)
17:31:33.748906 eth0 > wsasa3005.asa-ehv.ce.philips.com.1181 > asaehv.ce.philips.com.www: . 34:34(0) ack 21836 win 19389 (DF)
17:31:37.250061 eth0 > wsasa3005.asa-ehv.ce.philips.com.1181 > asaehv.ce.philips.com.www: P 34:39(5) ack 21836 win 19389 (DF)
17:31:37.250450 eth0 < asaehv.ce.philips.com.www > wsasa3005.asa-ehv.ce.philips.com.1181: R 3010023376:3010023376(0) win 8760 (DF)
17:31:37.251146 eth0 > wsasa3005.asa-ehv.ce.philips.com.1181 > asaehv.ce.philips.com.www: R 67:67(0) ack 21836 win 32120 (DF)

As you can see, the client TCP receives the RST (450-061) = 389 microsecs
after making the first write. I believe this time is sufficient enough for the
client TCP to fail on the second write() call, that was made probably after it had received
the RST. Or is it not ???

The other inconsistent behavior that I was talking about is that you can also see the client also
generating an RST and sending it back to the server after it had received an RST, when the second 
write() call was made slightly probably before 17:31:37.251146.

Please comment.

---

From: [email-masked]
Date: Wed, 28 Mar 2001 17:06:31 +0200

der Mouse and all,

As indicated by der Mouse, I performed two writes by making two connections to the server. 
I did find that data with the second write call made through the second connection appeared
on the wire before I could receive the RST from the first write (made from the first connection).
This clarifies der Mouse's point.

Thanks,
Rajiv

[email-masked]@[email-masked] on 03-28-2001 03:49:40 PM
Sent by:	[email-masked]
To:	Rajiv Chakravorty/EHV/CE/PHILIPS@EMEA3
cc:	[email-masked]@SMTP 
Subject:	Re: query: using two write() calls in succession
Classification:	

> I was under the impression that a blocking write (or send) call would
> block until it has received an ACK or an RST for data sent and then
> perform the 2nd write.

This is not the way any implementation I've used works (unless the
first write is larger than the buffering capacity of the socket).

> I have noticed that this happens even when I had made two write calls
> by breaking the request (1+32) while making the first normal request
> to the server.  (check the previous linuxdump.txt file).  I have
> appended relevant parts of it here:

> As you can see, when I make my first write call by sending 1 byte of
> data, it  waits until it receives the ACK and then proceed with the
> second write.

You are confusing the timing of the write() calls with the timing of
the data actually going out onto the wire.

> That means, in this case write call blocks until the server or peer
> TCP ackowledges the data.

No, it means that the TCP does not send the data until then.  It says
nothing about when the write calls complete (except, of course, that
the first write must have completed before the second write's data goes
out).

					der Mouse