Send all data to a socket before exit from Socket.Send.
authorDave Curylo <curylod@asme.org>
Wed, 21 Sep 2016 14:55:56 +0000 (10:55 -0400)
committerDave Curylo <curylod@asme.org>
Wed, 21 Sep 2016 15:31:53 +0000 (11:31 -0400)
mcs/class/System/System.Net.Sockets/Socket.cs
mcs/class/System/Test/System.Net.Sockets/SocketTest.cs

index 58d0899bf13325c69fe70745178f944d0750e54f..e4a318d22299f996bc9f36635f4ece24e9a10ab7 100644 (file)
@@ -2457,18 +2457,19 @@ namespace System.Net.Sockets
                        }
 
                        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)
index 4955d3f3c6096effcfa6a54a0c6dfb2a53b937e7..40242870f885508ff12488ad2488ff7730b4aa1d 100755 (executable)
@@ -2599,6 +2599,67 @@ namespace MonoTests.System.Net.Sockets
                        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 ()
                {