[Mono-bugs] [Bug 72185][Nor] New - Operation on non-blocking socket would block

bugzilla-daemon@bugzilla.ximian.com bugzilla-daemon@bugzilla.ximian.com
Thu, 3 Feb 2005 11:17:52 -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 monkey@gmx.info.

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

--- shadow/72185	2005-02-03 11:17:52.000000000 -0500
+++ shadow/72185.tmp.17423	2005-02-03 11:17:52.000000000 -0500
@@ -0,0 +1,229 @@
+Bug#: 72185
+Product: Mono: Runtime
+Version: 1.0
+OS: 
+OS Details: XP Pro SP2
+Status: NEW   
+Resolution: 
+Severity: 
+Priority: Normal
+Component: io-layer
+AssignedTo: mono-bugs@ximian.com                            
+ReportedBy: monkey@gmx.info               
+QAContact: mono-bugs@ximian.com
+TargetMilestone: ---
+URL: 
+Cc: 
+Summary: Operation on non-blocking socket would block
+
+Description of Problem:
+
+I created a simple server and client (see below). The communication between 
+them works fine if I use Microsoft's runtime environment. If I use Mono, 
+however, it fails with the following message:
+
+Unhandled Exception: System.Net.Sockets.SocketException: Operation on non-
+blocking socket would block
+
+Steps to reproduce the problem:
+
+Compile the following source code, run the server.exe and connect to it 
+using the client.exe (adjust the IP address accordingly). If all works 
+well, the client outputs "Request was echoed back correctly."
+
+using System;
+using System.Net;
+using System.Net.Sockets;
+using System.Diagnostics;
+
+namespace Packets
+{
+	public class Transfer
+	{
+		public static void SendData(byte[] data, Socket socket)
+		{
+			/* create packet */
+
+			/* prepend total size of packet */
+			Int32 size = new Int32();
+			size = 4 + data.Length;
+			byte[] packet = BitConverter.GetBytes(size);				
+
+			/* append data */
+			packet = Data.Merge(packet, data);			
+			
+			/* send all packet data */
+			Console.WriteLine(String.Format("Sending packet: {0} bytes ...", packet.
+Length));
+			socket.Send(packet);
+		}
+
+		public static byte[] ReceiveData(Socket socket)
+		{
+			/* read whole packet */			
+			byte[] buffer = new byte[1024 * 1024];
+
+			/* determine packet length */
+			int numRead = socket.Receive(buffer);		
+			Console.WriteLine(String.Format("Received first {0} bytes of packet.", 
+numRead));
+
+			int lengthPacket = BitConverter.ToInt32(buffer, 0);
+			int remaining = lengthPacket - numRead;
+			Console.WriteLine(String.Format("Receiving the remaining {0} bytes ...", 
+remaining));
+
+			/* read remaining bytes - if any */		
+			if(remaining > 0)
+				socket.Receive(buffer, numRead, remaining, SocketFlags.None);
+			
+                        
+			/* extract data (bytes 0 - 3 belong to packet size) */
+			byte[] data = Data.Slice(buffer, 4, lengthPacket - 1);
+
+			/* return data */	
+			return data;
+		}
+		
+	}
+
+}
+
+namespace Packets
+{
+	public class Data
+	{
+		public static byte[] Slice(byte[] array, int from, int upto)
+		{
+			/* create new array with enough capacity for the slice */
+			byte[] slice = new byte[upto - from + 1];
+
+			/* copy relevant items to slice array */
+			for(int i=from; i<=upto; i++)
+				slice[i-from] = array[i];
+
+			/* return resulting slice */
+			return slice;
+		}
+
+		public static byte[] Duplicate(byte[] array)
+		{
+			/* create new array with same capacity */
+			byte[] result = new byte[array.Length];
+
+			/* copy each element */
+			for(int i=0; i<array.Length; i++)
+				result[i] = array[i];
+
+			/* return resulting array */
+			return result;
+		}
+
+		public static byte[] Merge(byte[] arrayA, byte[] arrayB)
+		{
+			/* create new array with enough space for both arrays */
+			byte[] result = new byte[arrayA.Length + arrayB.Length];
+
+			/* copy items from first array */
+			for(int i=0; i<arrayA.Length; i++)
+				result[i] = arrayA[i];
+
+			/* append items from second array */
+			for(int i=arrayA.Length; i<result.Length; i++)
+				result[i] = arrayB[i-arrayA.Length];
+
+			/* return resulting array */
+			return result;
+		}
+	}
+}
+
+using System;
+using System.Net;
+using System.Net.Sockets;
+using System.Diagnostics;
+using Packets;
+
+public class Server
+{
+	public static void Main()
+	{
+		/* determine local address */
+		IPAddress address = Dns.GetHostByName(Dns.GetHostName()).AddressList[0];
+
+		/* listen for client connection */
+		TcpListener listener = new TcpListener(address, 8888);	
+		listener.Start();	
+		Console.WriteLine(String.Format("Listening @ {0} for client connection ..
+.", address));			
+
+		/* receive and process request packet */
+		Socket socket = listener.AcceptSocket();
+		byte[] request = Transfer.ReceiveData(socket);
+
+		/* check if data was received correctly */
+		for(int i=0; i<request.Length; i++)
+			if(request[i] != 1)
+			{
+				Console.WriteLine("Mismatch at {0}: Got {1}, expected 1.", i, 
+request[i]);
+				break;
+			}
+
+		/* echo request */
+		Transfer.SendData(request, socket);
+
+		/* close connection */
+		socket.Close();
+	}
+}
+
+
+using System;
+using System.Net;
+using System.Net.Sockets;
+using System.Diagnostics;
+
+using Packets;
+
+public class Client
+{
+	public static void Main(string[] args)
+	{
+		/* create remote address */
+		IPAddress address = IPAddress.Parse("192.168.0.26");
+
+		/* connect to remote address */
+		Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, 
+ProtocolType.Tcp);
+		socket.Connect(new IPEndPoint(address, 8888));
+
+		/* create dummy data */	
+		byte[] data = new byte[128 * 1024];
+		for(int i=0; i<data.Length; i++)
+			data[i] = 1;
+		
+		/* send data as packet to server */
+		Transfer.SendData(data, socket);
+
+		/* receive response packet and response data */	
+		byte[] response = Transfer.ReceiveData(socket);
+
+		/* compare response with request */
+		bool identical = true;
+		for(int i=0; i<response.Length; i++)
+			if(data[i] != response[i])
+			{
+				identical = false;
+				Console.WriteLine("Mismatch at {0}: Got {1}, expected 1.", i, 
+response[i]);
+				break;
+			}
+
+                if(identical)		
+			Console.WriteLine("Request was echoed back correctly.");
+
+		/* close connection */
+		socket.Close();
+	}
+}