[Mono-bugs] [Bug 53229][Maj] New - Using BeginReceive on a Socket causes SocketException in worker thread when Socket is closed

bugzilla-daemon@bugzilla.ximian.com bugzilla-daemon@bugzilla.ximian.com
Thu, 22 Jan 2004 14:45:21 -0500 (EST)


Please do not reply to this email- if you want to comment on the bug, go to the
URL shown below and enter your comments there.

Changed by jconley@winfessor.com.

http://bugzilla.ximian.com/show_bug.cgi?id=53229

--- shadow/53229	2004-01-22 14:45:21.000000000 -0500
+++ shadow/53229.tmp.18263	2004-01-22 14:45:21.000000000 -0500
@@ -0,0 +1,125 @@
+Bug#: 53229
+Product: Mono/Class Libraries
+Version: unspecified
+OS: 
+OS Details: Windows Server 2003 Enterprise Edition
+Status: NEW   
+Resolution: 
+Severity: Unknown
+Priority: Major
+Component: System
+AssignedTo: mono-bugs@ximian.com                            
+ReportedBy: jconley@winfessor.com               
+QAContact: mono-bugs@ximian.com
+TargetMilestone: ---
+URL: 
+Cc: 
+Summary: Using BeginReceive on a Socket causes SocketException in worker thread when Socket is closed
+
+Description of Problem: If the asynchronous BeginReceive method is used on 
+a System.Net.Sockets.Socket, an exception will be thrown in the worker 
+thread when the socket is closed, and the AsyncCallback specified in 
+BeginReceive will not be called.
+
+Steps to reproduce the problem:
+1. Create a InterNetwork TCP Socket with no flags.
+2. Connect the socket to something.
+3. Call BeginReceive and specify a callback.
+4. Close the socket.
+
+Actual Results:
+The following exception is thrown in the worker thread and printed to the 
+console and the user code is never notified.
+
+Unhandled Exception: System.Net.Sockets.SocketException: Some sort of w32 
+error occurred: 0
+in (unmanaged) (wrapper managed-to-native) 
+System.Net.Sockets.Socket:Receive_internal (intptr,byte
+[],int,int,System.Net.
+Sockets.SocketFlags)
+in <0x00004> (wrapper managed-to-native) 
+System.Net.Sockets.Socket:Receive_internal (intptr,byte
+[],int,int,System.Net.So
+ckets.SocketFlags)
+in [0x00054] (at /cvs/mcs/class/System/System.Net.Sockets/Socket.cs:872) 
+System.Net.Sockets.Socket:Receive (byte[],int,i
+nt,System.Net.Sockets.SocketFlags)
+in [0x00067] (at /cvs/mcs/class/System/System.Net.Sockets/Socket.cs:874) 
+System.Net.Sockets.Socket:Receive (byte[],int,i
+nt,System.Net.Sockets.SocketFlags)
+in [0x0003c] 
+(at /cvs/mcs/class/System/System.Net.Sockets/Socket.cs:184) .Worker:Receive
+ ()
+in <0x00044> (wrapper delegate-invoke) 
+System.MulticastDelegate:invoke_void ()
+
+
+Expected Results:
+No exception should occur.  Instead, the AsyncCallback should be called 
+and the subsequent call to EndReceive should return 0 bytes.
+
+How often does this happen? 
+Every time.
+
+Additional Information:
+Here's a VB.NET class that can be used to duplicate the problem.  I 
+haven't tried to compile it with Mono, but it runs fine after being 
+compiled with the MS compiler.
+
+Public Class BreakMonoSockets
+    Public Sub DontBreakIt()
+        System.Console.WriteLine("creating socket")
+        Dim s As New System.Net.Sockets.Socket
+(Net.Sockets.AddressFamily.InterNetwork, Net.Sockets.SocketType.Stream, 
+Net.Sockets.ProtocolType.Tcp)
+
+        System.Console.WriteLine("connecting to endpoint")
+        s.Connect(New System.Net.IPEndPoint(System.Net.Dns.GetHostByName
+("www.go-mono.org").AddressList(0), 80))
+
+        System.Console.WriteLine("closing socket")
+        s.Close()
+    End Sub
+
+    Public Sub BreakIt()
+        System.Console.WriteLine("creating socket")
+        Dim s As New System.Net.Sockets.Socket
+(Net.Sockets.AddressFamily.InterNetwork, Net.Sockets.SocketType.Stream, 
+Net.Sockets.ProtocolType.Tcp)
+
+        System.Console.WriteLine("connecting to endpoint")
+        s.Connect(New System.Net.IPEndPoint(System.Net.Dns.GetHostByName
+("www.go-mono.org").AddressList(0), 80))
+
+        System.Console.WriteLine("setting up beginreceive")
+        Dim receiveBuff(1024) As Byte
+        s.BeginReceive(receiveBuff, 0, receiveBuff.Length, 
+Net.Sockets.SocketFlags.None, AddressOf beginreceivecb, s)
+
+        System.Console.WriteLine("closing socket")
+        s.Close()
+    End Sub
+
+    Private Sub beginreceivecb(ByVal ar As IAsyncResult)
+        Try
+            Dim s As System.Net.Sockets.Socket = DirectCast(ar.AsyncState, 
+System.Net.Sockets.Socket)
+            Dim size As Integer = s.EndReceive(ar)
+
+            System.Console.WriteLine("beginreceivecb called with " & size 
+& " bytes received")
+
+            If size > 0 Then
+                System.Console.WriteLine("called beginreceive again")
+                Dim receiveBuff(1024) As Byte
+                s.BeginReceive(receiveBuff, 0, receiveBuff.Length, 
+Net.Sockets.SocketFlags.None, AddressOf beginreceivecb, s)
+            Else
+                System.Console.WriteLine("size was less than or equal to 
+0")
+            End If
+        Catch ex As Exception
+            System.Console.WriteLine("exception occurred in 
+beginreceivecb: " & ex.ToString)
+        End Try
+    End Sub