[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();
+ }
+}