Opened 11 years ago

Closed 10 years ago

#6698 closed Bugs (invalid)

WSASend synchronous send/close failure with latency

Reported by: thrawy@… Owned by: chris_kohlhoff
Milestone: To Be Determined Component: asio
Version: Boost 1.47.0 Severity: Problem
Keywords: syncrhonous WSASend latency Cc:

Description

After making a synchronous socket call (send(), write() or close()) that returns success, if the calling thread exits quickly, on connections with ~500 ms latency, the operation doesn't actually take place. (With little latency the problem does not occur.)

With the following code snippet, send() returns the correct size for the buffer and ec.value() remains 0. However, using wireshark at the remote, the data never arrives.

boost::system::error_code ec;
size_t nWritten = m_sock->send( <some data>, ec );
assert( nWritten == <data size> );
assert( !ec.value() );
m_sock->close( ec );
assert( !ec.value() );

m_io_service->stop();
m_thread->join();

This occurs both with linger on and off. I was able to verify this on several different systems running 32 and 64 bit windows 7. By putting an assert in socket_ops.ipp immediately after its call to WSASend() I was able to verify that it returned success and WSAGetLastError() returned 0.

If I add a brief ::Sleep(100) call immediately after the socket calls fixes the problem and the data is transmitted and received at the other end.

My thought is that this is a Windows error - when a socket is created using WSASocket() with WSA_FLAG_OVERLAPPED set (as asio does), a call to WSASend() with the overlapped arguments set to 0 isn't truly performed synchronously.

I couldn't find this bug previously reported anywhere, if it is I apologize.

Thanks Hugh

Change History (1)

comment:1 by chris_kohlhoff, 10 years ago

Resolution: invalid
Status: newclosed

On some versions of Windows, closing the socket while there is still buffered data may result in data loss. Try using a strategy for graceful close, e.g. half closing the socket (using shutdown) and then waiting for the peer to close once it has received all the data (which means a subsequent receive call in your program will fail with asio::error::eof).

Last edited 10 years ago by chris_kohlhoff (previous) (diff)
Note: See TracTickets for help on using tickets.