Why do I get SocketExceptions on NetCF when setting some socket options?
I am frequently asked why NetCF applications encounter a SocketException when attempting to use some socket options, when applications written to the full .NET Framework do not. The companion question is invariably "Is this a bug in NetCF?".
If the result is WSAENOPROTOOPT (10042), what we are seeing is limitations of the operating system -- in this case, Windows CE -- so the answer is “no, this is not a bug, it is a limiation of the underlying operating system.“
Since the beginning, the .NET Compact Framework was designed to be portable -- run on more than one operating system. Because of this, we did not limit the available options in the SocketOptionNames enum. When calling Socket.GetSocketOption() or Socket.SetSocketOption(), the request is forwarded on to the operating system to do the work. If the result is a failure, the return code is wrapped into a SocketException and thrown.
The list of socket options which you can expect to throw, as described above, can be seen below (taken from the Windows CE API reference).
GetSocketOption
BSD options not supported for getsockopt are as follows.
Value | Type | Description |
---|---|---|
SO_RCVLOWAT | int | Retrieves recv low watermark. |
SO_RCVTIMEO | int | Retrieves recv time-out value. |
SO_SNDLOWAT | int | Retrieves send low watermark. |
SO_SNDTIMEO | int | Retrieves time-out value for send. |
TCP_MAXSEG | int | RetrievesTCP maximum-segment size. |
Note: The above table taken from the MSDN documentation for getsockopt .
SetSocketOption
The following table shows BSD options not supported for setsockopt .
Value | Type | Description |
---|---|---|
SO_ACCEPTCONN | BOOL | Sets socket listening. |
SO_RCVLOWAT | int | Sets recv low watermark. |
SO_RCVTIMEO | int | Sets time-out for recv. |
SO_SNDLOWAT | int | Sets send low watermark. |
SO_SNDTIMEO | int | Sets time-out value for send. |
SO_TYPE | Int | Sets socket type. |
Note: The above table taken from the MSDN documentation for setsockopt .
If you are writing portable code (runs on both the .NET Framework and the .NET Compact Framework), you will need to handle this exception and change your application behavior as needed. For example, you may wish to disable controls related to expert socket features (ex: Receive Timeout). The code fragment below shows
using System.Net;
using System.Net.Sockets;
class SocketHelpers
{
bool ReceiveTimeoutSupported(Socket socket)
{
try
{
// try to get ReceiveTimeout option (this will get the default value)
Int32 timeout = (Int32)socket.GetSocketOption(SocketOptionLevel.Socket,
SocketOptionName.ReceiveTimeout);
// try to set what we received (we don't want to change the default value)
socket.SetSocketOption(SocketOptionLevel.Socket,
SocketOptionName.ReceiveTimeout,
timeout);
// if we get here, ReceiveTimeout is supported
return true;
}
catch(SocketException e)
{
// check to see if the selected option is supported
if(10042 != e.ErrorCode) // WSAENOPROTOOPT
{
// ReceiveTimeout not supported by operating system
return false;
}
else
{
// no, let the caller handle the exception
throw;
}
}
}
}
I hope this helps clear up some of the confusion around socket options and the .Net Compact Framework.
-- DK
Disclaimer:
This posting is provided "AS IS" with no warranties, and confers no rights.
Comments
- Anonymous
July 15, 2004
David
Thanks for this info again.
Do you have any idea then of how to see outgoing and incoming packets to count the number of bytes going throught the ports.
since socket.raw does not work on PPC and IOControl(RCVALL) also ?
thanks
Jonathan - Anonymous
July 27, 2004
Jonathan,
Take a look at this link from MSDN. While it's a Windows CE article, what you are looking for is likely in older (4.x, 3.0) versions as well.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wcecomm5/html/wce50grfIPHelperReference.asp
Hope this helps!
--DK - Anonymous
September 05, 2006
PingBack from http://blog.marciosete.com/2006/09/05/blodding-socket/