Make wxSocket::Peek() work with UDP too

Fix wxSocketImpl::RecvDgram() when caller requests fewer bytes than
are present in datagram, as we must always read all the available bytes
when using UDP -- they are not buffered by the OS and so won't be
provided by the next Read() call.

Closes #23594.

Closes #23604.
This commit is contained in:
Brian Nixon 2023-06-03 20:29:22 +01:00 committed by Vadim Zeitlin
parent 5546733c12
commit b9d0541f9a
2 changed files with 93 additions and 3 deletions

View file

@ -302,4 +302,60 @@ void SocketTestCase::UrlTest()
CPPUNIT_ASSERT_EQUAL( wxSTREAM_EOF, in->Read(out).GetLastError() );
}
TEST_CASE("wxDatagramSocket::ShortRead", "[socket][dgram]")
{
// Check that reading fewer bytes than are present in a
// datagram does not leave the socket in an error state
wxIPV4address addr;
addr.LocalHost();
addr.Service(19898);// Arbitrary port number
wxDatagramSocket sock(addr);
// Send ourselves a datagram
unsigned int sendbuf[4] = {1, 2, 3, 4};
sock.SendTo(addr, sendbuf, sizeof(sendbuf));
// Read less than we know we sent
unsigned int recvbuf[1] = {0};
sock.Read(recvbuf, sizeof(recvbuf));
CHECK(!sock.Error());
CHECK(sock.LastReadCount() == sizeof(recvbuf));
CHECK(recvbuf[0] == sendbuf[0]);
}
TEST_CASE("wxDatagramSocket::ShortPeek", "[socket][dgram]")
{
// Check that peeking fewer bytes than are present in a datagram
// does not lose the rest of the data in that datagram (#23594)
wxIPV4address addr;
addr.LocalHost();
addr.Service(27384);// Arbitrary port number
wxDatagramSocket sock(addr);
// Send ourselves 2 datagrams
unsigned int sendbuf1[2] = {1, 2};
sock.SendTo(addr, sendbuf1, sizeof(sendbuf1));
unsigned int sendbuf2[2] = {3, 4};
sock.SendTo(addr, sendbuf2, sizeof(sendbuf2));
long timeout_s = 1;
if ( !sock.WaitForRead(timeout_s) )
return;
// Peek the first word
unsigned int peekbuf[1] = {0};
sock.Peek(peekbuf, sizeof(peekbuf));
CHECK(sock.LastCount() == sizeof(peekbuf));
CHECK(peekbuf[0] == sendbuf1[0]);
// Read the whole of the first datagram
unsigned int recvbuf[2] = {0};
sock.Read(recvbuf, sizeof(recvbuf));
CHECK(sock.LastReadCount() == sizeof(recvbuf));
CHECK(recvbuf[0] == sendbuf1[0]);
CHECK(recvbuf[1] == sendbuf1[1]);
}
#endif // wxUSE_SOCKETS