From a1b1a7c8db1a74eb9d07ecc216dae59bce3f1ea0 Mon Sep 17 00:00:00 2001 From: Dave Curylo Date: Wed, 21 Sep 2016 10:55:56 -0400 Subject: [PATCH] Send all data to a socket before exit from Socket.Send. --- mcs/class/System/System.Net.Sockets/Socket.cs | 23 +++---- .../Test/System.Net.Sockets/SocketTest.cs | 61 +++++++++++++++++++ 2 files changed, 73 insertions(+), 11 deletions(-) diff --git a/mcs/class/System/System.Net.Sockets/Socket.cs b/mcs/class/System/System.Net.Sockets/Socket.cs index 58d0899bf133..e4a318d22299 100644 --- a/mcs/class/System/System.Net.Sockets/Socket.cs +++ b/mcs/class/System/System.Net.Sockets/Socket.cs @@ -2457,18 +2457,19 @@ int Send_nochecks (byte [] buf, int offset, int size, SocketFlags flags, out Soc } int nativeError; - int ret = Send_internal (safe_handle, buf, offset, size, flags, out nativeError); - - error = (SocketError)nativeError; - - if (error != SocketError.Success && error != SocketError.WouldBlock && error != SocketError.InProgress) { - is_connected = false; - is_bound = false; - } else { - is_connected = true; - } + int sent = 0; + do { + sent += Send_internal (safe_handle, buf, offset + sent, size - sent, flags, out nativeError); + error = (SocketError)nativeError; + if (error != SocketError.Success && error != SocketError.WouldBlock && error != SocketError.InProgress) { + is_connected = false; + is_bound = false; + } else { + is_connected = true; + } + } while (sent < size); - return ret; + return sent; } public bool SendAsync (SocketAsyncEventArgs e) diff --git a/mcs/class/System/Test/System.Net.Sockets/SocketTest.cs b/mcs/class/System/Test/System.Net.Sockets/SocketTest.cs index 4955d3f3c609..40242870f885 100755 --- a/mcs/class/System/Test/System.Net.Sockets/SocketTest.cs +++ b/mcs/class/System/Test/System.Net.Sockets/SocketTest.cs @@ -2599,6 +2599,67 @@ public void SendGeneric () listensock.Close (); } + [Test] + public void ConcurrentExceedSocketLimit () + { + var tasks = new Task[4]; + for (int i = 0; i < 4; i++) { + tasks[i] = Task.Factory.StartNew (() => SendGenericExceedBuffer ()); + } + Task.WaitAll (tasks); + } + + [Test] + public void SendGenericExceedBuffer () + { + // Create a buffer larger than the default max. + const int BUFFER_SIZE = 256 * 256 * 65; + int i; + + IPEndPoint endpoint = new IPEndPoint(IPAddress.Loopback, NetworkHelpers.FindFreePort ()); + + Socket listensock = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + listensock.Bind (endpoint); + listensock.Listen (1); + + Socket sendsock = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + sendsock.Connect (endpoint); + + Socket clientsock = listensock.Accept (); + + byte[] sendbuf = new byte[BUFFER_SIZE]; + + for (i = 0; i < BUFFER_SIZE; i++) { + sendbuf[i] = (byte)i; + } + + SocketError err; + int sent = sendsock.Send (sendbuf); + + Assert.AreEqual (BUFFER_SIZE, sent, "#1"); + + byte[] recvbuf = new byte[BUFFER_SIZE]; + + int totalReceived = 0; + byte[] buffer = new byte[256]; + while (totalReceived < sendbuf.Length) { + int recvd = clientsock.Receive (buffer, 0, buffer.Length, SocketFlags.None); + buffer.CopyTo (recvbuf, totalReceived); + totalReceived += recvd; + } + + Assert.AreEqual (BUFFER_SIZE, totalReceived, "#2"); + + for (i = 0; i < BUFFER_SIZE; i++) { + Assert.AreEqual (recvbuf[i], sendbuf[i], + "#3/" + i.ToString()); + } + + sendsock.Close (); + clientsock.Close (); + listensock.Close (); + } + [Test] public void ListenNotBound () {