Forráskód Böngészése

Fix async sockets: don't set Count=0 when reusing SocketAsyncEventArgs.

This reverts commit e2e44bf6f444320947ffa124d3b7c20968e493a5 (from May
2011).

Added SocketAsyncTest.cs to test this.
Martin Baulig 13 éve
szülő
commit
eb0ef90fc4

+ 0 - 1
mcs/class/System/System.Net.Sockets/Socket_2_1.cs

@@ -496,7 +496,6 @@ namespace System.Net.Sockets {
 				args.SetLastOperation (async_op);
 				args.SocketError = SocketError.Success;
 				args.BytesTransferred = 0;
-                                args.Count = 0;
 			}
 
 			public void Accept ()

+ 1 - 0
mcs/class/System/System_test.dll.sources

@@ -247,6 +247,7 @@ System.Net.Sockets/TcpListenerTest.cs
 System.Net.Sockets/SocketTest.cs
 System.Net.Sockets/SocketAsyncEventArgsTest.cs
 System.Net.Sockets/UdpClientTest.cs
+System.Net.Sockets/SocketAsyncTest.cs
 System.Net.Mail/LinkedResourceTest.cs
 System.Net.Mail/AttachmentCollectionTest.cs
 System.Net.Mail/MailAddressCollectionTest.cs

+ 136 - 0
mcs/class/System/Test/System.Net.Sockets/SocketAsyncTest.cs

@@ -0,0 +1,136 @@
+using System;
+using System.Collections;
+using System.Threading;
+using System.Net;
+using System.Net.Sockets;
+using NUnit.Framework;
+
+namespace MonoTests.System.Net.Sockets
+{
+	[TestFixture]
+	public class SocketAsyncTest
+	{
+		Socket serverSocket;
+		Socket clientSocket;
+		ManualResetEvent readyEvent;
+		ManualResetEvent mainEvent;
+		Exception error;
+
+		[TestFixtureSetUp]
+		public void SetUp ()
+		{
+			readyEvent = new ManualResetEvent (false);
+			mainEvent = new ManualResetEvent (false);
+
+			ThreadPool.QueueUserWorkItem (_ => DoWork ());
+			readyEvent.WaitOne ();
+
+			clientSocket = new Socket (
+				AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
+			clientSocket.Connect (serverSocket.LocalEndPoint);
+			clientSocket.NoDelay = true;
+		}
+
+		[TestFixtureTearDown]
+		public void TearDown ()
+		{
+			if (serverSocket != null)
+				serverSocket.Close ();
+			readyEvent.Close ();
+			mainEvent.Close ();
+		}
+
+		void DoWork ()
+		{
+			serverSocket = new Socket (
+				AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
+			serverSocket.Bind (new IPEndPoint (IPAddress.Loopback, 0));
+			serverSocket.Listen (1);
+
+			var async = new SocketAsyncEventArgs ();
+			async.Completed += (s,e) => OnAccepted (e);
+
+			readyEvent.Set ();
+
+			if (!serverSocket.AcceptAsync (async))
+				OnAccepted (async);
+		}
+
+		void OnAccepted (SocketAsyncEventArgs e)
+		{
+			var acceptSocket = e.AcceptSocket;
+
+			try {
+				var header = new byte [4];
+				acceptSocket.Receive (header);
+				if ((header [0] != 0x12) || (header [1] != 0x34) ||
+				    (header [2] != 0x56) || (header [3] != 0x78))
+					throw new InvalidOperationException ();
+			} catch (Exception ex) {
+				error = ex;
+				return;
+			}
+
+			var recvAsync = new SocketAsyncEventArgs ();
+			recvAsync.Completed += (sender, args) => OnReceived (args);
+			recvAsync.SetBuffer (new byte [4], 0, 4);
+			if (!acceptSocket.ReceiveAsync (recvAsync))
+				OnReceived (recvAsync);
+
+			mainEvent.Set ();
+		}
+
+		void OnReceived (SocketAsyncEventArgs e)
+		{
+			if (e.SocketError != SocketError.Success)
+				error = new SocketException ((int) e.SocketError);
+			else if (e.Buffer [0] != 0x9a)
+				error = new InvalidOperationException ();
+
+			mainEvent.Set ();
+		}
+
+		[Test]
+		[Category("Test")]
+		public void SendAsync ()
+		{
+			var buffer = new byte [] { 0x12, 0x34, 0x56, 0x78 };
+			var m = new ManualResetEvent (false);
+			var e = new SocketAsyncEventArgs ();
+			e.SetBuffer (buffer, 0, buffer.Length);
+			e.Completed += (s,o) => {
+				if (o.SocketError != SocketError.Success)
+					error = new SocketException ((int)o.SocketError);
+				m.Set ();
+			};
+			bool res = clientSocket.SendAsync (e);
+			if (res) {
+				if (!m.WaitOne (1500))
+					throw new TimeoutException ();
+			}
+
+			if (!mainEvent.WaitOne (1500))
+				throw new TimeoutException ();
+			if (error != null)
+				throw error;
+
+			m.Reset ();
+			mainEvent.Reset ();
+
+			buffer [0] = 0x9a;
+			buffer [1] = 0xbc;
+			buffer [2] = 0xde;
+			buffer [3] = 0xff;
+			res = clientSocket.SendAsync (e);
+			if (res) {
+				if (!m.WaitOne (1500))
+					throw new TimeoutException ();
+			}
+
+			if (!mainEvent.WaitOne (1500))
+				throw new TimeoutException ();
+			if (error != null)
+				throw error;
+		}
+	}
+}