[Mono-dev] [PATCH] Missing Socket.Send and Socket.Receive methods

Tomi Valkeinen tomba at bat.org
Mon Apr 10 06:17:05 EDT 2006


Hi,

Included is a patch that implements the missing Socket.Send and 
Socket.Receive methods that take SocketError as an out parameter. These 
methods do not throw an exception when an error occurs (such as 
WouldBlock) and so are quite essential for non-blocking socket IO. I also 
changed the SocketError enum to be internal in .Net 1.x version of the 
class lib, so that it can be used in socket code instead of those horrible 
if (error != 10035) checks.

I've also made a similar Socket.Connect method, but that's not included as 
Microsoft's .Net framework does not have such a method. What is the policy 
on non-standard methods?

  Tomi
-------------- next part --------------
Index: mcs/class/System/System.Net.Sockets/Socket.cs
===================================================================
--- mcs/class/System/System.Net.Sockets/Socket.cs	(revision 59285)
+++ mcs/class/System/System.Net.Sockets/Socket.cs	(working copy)
@@ -1318,7 +1318,14 @@
 			if (buf == null)
 				throw new ArgumentNullException ("buf");
 
-			return Receive_nochecks (buf, 0, buf.Length, SocketFlags.None);
+			SocketError error;
+
+			int ret = Receive_nochecks (buf, 0, buf.Length, SocketFlags.None, out error);
+			
+			if (error != SocketError.Success)
+				throw new SocketException ((int)error);
+
+			return ret;
 		}
 
 		public int Receive (byte [] buf, SocketFlags flags)
@@ -1329,7 +1336,14 @@
 			if (buf == null)
 				throw new ArgumentNullException ("buf");
 
-			return Receive_nochecks (buf, 0, buf.Length, flags);
+			SocketError error;
+
+			int ret = Receive_nochecks (buf, 0, buf.Length, flags, out error);
+			
+			if (error != SocketError.Success)
+				throw new SocketException ((int)error);
+
+			return ret;
 		}
 
 		public int Receive (byte [] buf, int size, SocketFlags flags)
@@ -1343,17 +1357,16 @@
 			if (size < 0 || size > buf.Length)
 				throw new ArgumentOutOfRangeException ("size");
 
-			return Receive_nochecks (buf, 0, size, flags);
+			SocketError error;
+
+			int ret = Receive_nochecks (buf, 0, size, flags, out error);
+			
+			if (error != SocketError.Success)
+				throw new SocketException ((int)error);
+
+			return ret;
 		}
 
-		[MethodImplAttribute(MethodImplOptions.InternalCall)]
-		private extern static int Receive_internal(IntPtr sock,
-							   byte[] buffer,
-							   int offset,
-							   int count,
-							   SocketFlags flags,
-							   out int error);
-
 		public int Receive (byte [] buf, int offset, int size, SocketFlags flags)
 		{
 			if (disposed && closed)
@@ -1368,24 +1381,58 @@
 			if (size < 0 || offset + size > buf.Length)
 				throw new ArgumentOutOfRangeException ("size");
 			
-			return Receive_nochecks (buf, offset, size, flags);
+			SocketError error;
+
+			int ret = Receive_nochecks (buf, offset, size, flags, out error);
+			
+			if(error != SocketError.Success)
+				throw new SocketException ((int)error);
+
+			return ret;
 		}
 
-		int Receive_nochecks (byte [] buf, int offset, int size, SocketFlags flags)
+#if NET_2_0
+		public int Receive (byte[] buf,	int offset,	int size, SocketFlags flags, out SocketError error)
 		{
-			int ret, error;
+			if (disposed && closed)
+				throw new ObjectDisposedException (GetType ().ToString ());
+
+			if (buf == null)
+				throw new ArgumentNullException ("buf");
+
+			if (offset < 0 || offset > buf.Length)
+				throw new ArgumentOutOfRangeException ("offset");
+
+			if (size < 0 || offset + size > buf.Length)
+				throw new ArgumentOutOfRangeException ("size");
 			
-			ret = Receive_internal (socket, buf, offset, size, flags, out error);
+			int ret = Receive_nochecks (buf, offset, size, flags, out error);
+			
+			return ret;
+		}
+#endif
 
-			if (error != 0) {
-				if (error != 10035 && error != 10036) // WSAEWOULDBLOCK && WSAEINPROGRESS
-					connected = false;
+		[MethodImplAttribute(MethodImplOptions.InternalCall)]
+		private extern static int Receive_internal(IntPtr sock,
+							   byte[] buffer,
+							   int offset,
+							   int count,
+							   SocketFlags flags,
+							   out int error);
 
-				throw new SocketException (error);
-			}
+		int Receive_nochecks (byte [] buf, int offset, int size, SocketFlags flags, out SocketError error)
+		{
+			int nativeError;
+			
+			int ret = Receive_internal (socket, buf, offset, size, flags, out nativeError);
 
-			connected = true;
+			error = (SocketError)nativeError;
 
+			if (error != SocketError.Success && error != SocketError.WouldBlock && error != SocketError.InProgress)
+				connected = false;
+			else
+				connected = true;
+			
 			return ret;
 		}
 		
@@ -1506,7 +1553,14 @@
 			if (buf == null)
 				throw new ArgumentNullException ("buf");
 
-			return Send_nochecks (buf, 0, buf.Length, SocketFlags.None);
+			SocketError error;
+
+			int ret = Send_nochecks (buf, 0, buf.Length, SocketFlags.None, out error);
+
+			if (error != SocketError.Success)
+				throw new SocketException ((int)error);
+
+			return ret;
 		}
 
 		public int Send (byte [] buf, SocketFlags flags)
@@ -1517,7 +1571,14 @@
 			if (buf == null)
 				throw new ArgumentNullException ("buf");
 
-			return Send_nochecks (buf, 0, buf.Length, flags);
+			SocketError error;
+
+			int ret = Send_nochecks (buf, 0, buf.Length, flags, out error);
+
+			if (error != SocketError.Success)
+				throw new SocketException ((int)error);
+
+			return ret;
 		}
 
 		public int Send (byte [] buf, int size, SocketFlags flags)
@@ -1531,16 +1592,16 @@
 			if (size < 0 || size > buf.Length)
 				throw new ArgumentOutOfRangeException ("size");
 
-			return Send_nochecks (buf, 0, size, flags);
+			SocketError error;
+
+			int ret = Send_nochecks (buf, 0, size, flags, out error);
+
+			if (error != SocketError.Success)
+				throw new SocketException ((int)error);
+
+			return ret;
 		}
 
-		[MethodImplAttribute(MethodImplOptions.InternalCall)]
-		private extern static int Send_internal(IntPtr sock,
-							byte[] buf, int offset,
-							int count,
-							SocketFlags flags,
-							out int error);
-
 		public int Send (byte [] buf, int offset, int size, SocketFlags flags)
 		{
 			if (disposed && closed)
@@ -1555,27 +1616,62 @@
 			if (size < 0 || offset + size > buf.Length)
 				throw new ArgumentOutOfRangeException ("size");
 
-			return Send_nochecks (buf, offset, size, flags);
+			SocketError error;
+
+			int ret = Send_nochecks (buf, offset, size, flags, out error);
+
+			if (error != SocketError.Success)
+				throw new SocketException ((int)error);
+
+			return ret;
 		}
 
-		int Send_nochecks (byte [] buf, int offset, int size, SocketFlags flags)
+#if NET_2_0
+		public int Send (byte [] buf, int offset, int size, SocketFlags flags, out SocketError error)
 		{
-			if (size == 0)
-				return 0;
+			if (disposed && closed)
+				throw new ObjectDisposedException (GetType ().ToString ());
 
-			int ret, error;
+			if (buf == null)
+				throw new ArgumentNullException ("buffer");
 
-			ret = Send_internal (socket, buf, offset, size, flags, out error);
+			if (offset < 0 || offset > buf.Length)
+				throw new ArgumentOutOfRangeException ("offset");
 
-			if (error != 0) {
-				if (error != 10035 && error != 10036) // WSAEWOULDBLOCK && WSAEINPROGRESS
-					connected = false;
+			if (size < 0 || offset + size > buf.Length)
+				throw new ArgumentOutOfRangeException ("size");
 
-				throw new SocketException (error);
+			int ret = Send_nochecks (buf, offset, size, flags, out error);
+
+			return ret;
+		}
+#endif
+
+		[MethodImplAttribute(MethodImplOptions.InternalCall)]
+		private extern static int Send_internal(IntPtr sock,
+							byte[] buf, int offset,
+							int count,
+							SocketFlags flags,
+							out int error);
+
+		int Send_nochecks (byte [] buf, int offset, int size, SocketFlags flags, out SocketError error)
+		{
+			if (size == 0) {
+				error = SocketError.Success;
+				return 0;
 			}
 
-			connected = true;
+			int nativeError;
 
+			int ret = Send_internal (socket, buf, offset, size, flags, out nativeError);
+
+			error = (SocketError)nativeError;
+
+			if (error != SocketError.Success && error != SocketError.WouldBlock && error != SocketError.InProgress)
+				connected = false;
+			else
+				connected = true;
+
 			return ret;
 		}
 
Index: mcs/class/System/System.Net.Sockets/SocketError.cs
===================================================================
--- mcs/class/System/System.Net.Sockets/SocketError.cs	(revision 59285)
+++ mcs/class/System/System.Net.Sockets/SocketError.cs	(working copy)
@@ -28,11 +28,14 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-#if NET_2_0
-
 namespace System.Net.Sockets
 {
-	public enum SocketError
+#if NET_2_0
+	public
+#else
+	internal
+#endif
+	enum SocketError
 	{
 		AccessDenied = 10013,
 		AddressAlreadyInUse = 10048,
@@ -83,5 +86,3 @@
 		WouldBlock = 10035
 	}
 }
-
-#endif


More information about the Mono-devel-list mailing list