G
Guest
I'm working on a webdav client which makes multiple webrequests using the
threadpool.
The initial issue was that some requests never returned, though I could
attach to the application and see they were still blocked at
webReq.GetResponse(). I finally fired up netmon to see where the connection
seemed to be getting lost, and it seems to be a race condition in the TCP
handling. Since I know next to nothing about TCP, or asynchronous
programming hopefully somone else can shed some more light on the issue.
When I see the issue, two threads are sending requests from the same client
port, and one server response overlaps a client ack in transit. This makes
me think that the client views this as having lost a packet and needing to
retransmit. However, the server response which caused the retransmit is
ignored, causing one of the client requests to wait forever for the server to
send a packet which the client has already recieved.
This is a simplified version of the trace data- client sequence numbers are
10+, servers are 110+, they're not continuous since there are other threads
sending data as well.
packet order (client) || Time || Source -> Dest || Ack# || Seq# || Request
type || Verb
4 4.633 C -> S 100 10 HTTP MKCOL
5 4.828 S -> C 20 100 TCP (ack)
6 4.828 C -> S 110 20 HTTP PROPPATCH
7 4.929 S -> C 30 110 HTTP 201 - created
8 5.112 C -> S 120 30 TCP (ack)
9 5.113 S -> C 30 120 HTTP 100 - continue
10 5.313 C -> S 130 30 TCP (ack)
So packets 8 and 9 are transmitted at the same time, so the client resends
packet 8 as packet 10. However, packet 9 which should trigger the body of
the 'proppatch' request, is never handled by the client.
Anyway- I realize this is long and rambling, so thanks to anyone who read
this far, and double thanks if you have any suggestions either for work
arounds or additional debugging.
threadpool.
The initial issue was that some requests never returned, though I could
attach to the application and see they were still blocked at
webReq.GetResponse(). I finally fired up netmon to see where the connection
seemed to be getting lost, and it seems to be a race condition in the TCP
handling. Since I know next to nothing about TCP, or asynchronous
programming hopefully somone else can shed some more light on the issue.
When I see the issue, two threads are sending requests from the same client
port, and one server response overlaps a client ack in transit. This makes
me think that the client views this as having lost a packet and needing to
retransmit. However, the server response which caused the retransmit is
ignored, causing one of the client requests to wait forever for the server to
send a packet which the client has already recieved.
This is a simplified version of the trace data- client sequence numbers are
10+, servers are 110+, they're not continuous since there are other threads
sending data as well.
packet order (client) || Time || Source -> Dest || Ack# || Seq# || Request
type || Verb
4 4.633 C -> S 100 10 HTTP MKCOL
5 4.828 S -> C 20 100 TCP (ack)
6 4.828 C -> S 110 20 HTTP PROPPATCH
7 4.929 S -> C 30 110 HTTP 201 - created
8 5.112 C -> S 120 30 TCP (ack)
9 5.113 S -> C 30 120 HTTP 100 - continue
10 5.313 C -> S 130 30 TCP (ack)
So packets 8 and 9 are transmitted at the same time, so the client resends
packet 8 as packet 10. However, packet 9 which should trigger the body of
the 'proppatch' request, is never handled by the client.
Anyway- I realize this is long and rambling, so thanks to anyone who read
this far, and double thanks if you have any suggestions either for work
arounds or additional debugging.