Windows get socket error

I am retrieving data from the socket using the following code iResult = recv(Socket,data_array,sizeof(data_array),0); Now the documentation states that if recv is succefull it would return the n...

I am retrieving data from the socket using the following code

iResult =  recv(Socket,data_array,sizeof(data_array),0);

Now the documentation states that if recv is succefull it would return the no. of bytes retrieved otherwise it would return an error code. How do I check for that error code. I mean what if the data retrieved is the same amount as the value of error code.

asked Aug 12, 2013 at 18:39

Rajeshwar's user avatar

If the return value is negative (i.e. SOCKET_ERROR or -1), that’s an error.

answered Aug 12, 2013 at 18:41

mark's user avatar

markmark

5,2492 gold badges20 silver badges34 bronze badges

Check this link to get some more detail.

Basically, when an error occurs, SOCKET_ERROR (-1) gets returned, and you then have to call WSAGetLastError(), or read errno or other platform-specific equivalent, to get the specific error code.

Remy Lebeau's user avatar

Remy Lebeau

536k30 gold badges444 silver badges750 bronze badges

answered Aug 12, 2013 at 19:53

eli's user avatar

elieli

3111 gold badge2 silver badges10 bronze badges

Now the documentation states that if recv is succefull it would return the no. of bytes retrieved otherwise it would return an error code.

No, it doesn’t say that at all. Read it again. It says it returns the number of bytes transferred if successful, otherwise -1, with the error available in errno, or in Windows via WSAGetLastError().

How do I check for that error code. I mean what if the data retrieved is the same amount as the value of error code.

You can’t transfer -1 bytes. There is no ambiguity.

answered Aug 13, 2013 at 1:59

user207421's user avatar

This blog post was originally posted on JetBrains .NET blog.

Rider consists of several processes that send messages to each other via sockets. To ensure the reliability of the whole application, it’s important to properly handle all the socket errors. In our codebase, we had the following code which was adopted from Mono Debugger Libs and helps us communicate with debugger processes:

protected virtual bool ShouldRetryConnection (Exception ex, int attemptNumber)
{
    var sx = ex as SocketException;
    if (sx != null) {
        if (sx.ErrorCode == 10061) //connection refused
            return true;
    }
    return false;
}

In the case of a failed connection because of a “ConnectionRefused” error, we are retrying the connection attempt. It works fine with .NET Framework and Mono. However, once we migrated to .NET Core, this method no longer correctly detects the “connection refused” situation on Linux and macOS. If we open the SocketException documentation, we will learn that this class has three different properties with error codes:

  • SocketError SocketErrorCode: Gets the error code that is associated with this exception.
  • int ErrorCode: Gets the error code that is associated with this exception.
  • int NativeErrorCode: Gets the Win32 error code associated with this exception.

What’s the difference between these properties? Should we expect different values on different runtimes or different operating systems? Which one should we use in production? Why do we have problems with ShouldRetryConnection on .NET Core? Let’s figure it all out!

Digging into the problem

Let’s start with the following program, which prints error code property values for SocketError.ConnectionRefused:

var se = new SocketException((int) SocketError.ConnectionRefused);
Console.WriteLine((int)se.SocketErrorCode);
Console.WriteLine(se.ErrorCode);
Console.WriteLine(se.NativeErrorCode);

If we run it on Windows, we will get the same value on .NET Framework, Mono, and .NET Core:

SocketErrorCode ErrorCode NativeErrorCode
.NET Framework 10061 10061 10061
Mono 10061 10061 10061
.NET Core 10061 10061 10061

10061 corresponds to the code of the connection refused socket error code in Windows (also known as WSAECONNREFUSED).
Now let’s run the same program on Linux:

SocketErrorCode ErrorCode NativeErrorCode
Mono 10061 10061 10061
.NET Core 10061 111 111

As you can see, Mono returns Windows-compatible error codes. The situation with .NET Core is different: it returns a Windows-compatible value for SocketErrorCode (10061) and a Linux-like value for ErrorCode and NativeErrorCode (111).
Finally, let’s check macOS:

SocketErrorCode ErrorCode NativeErrorCode
Mono 10061 10061 10061
.NET Core 10061 61 61

Here, Mono is completely Windows-compatible again, but .NET Core returns 61 for ErrorCode and NativeErrorCode.
In the IBM Knowledge Center, we can find a few more values for the connection refused error code from the Unix world (also known as ECONNREFUSED):

  • AIX: 79
  • HP-UX: 239
  • Solaris: 146

For a better understanding of what’s going on, let’s check out the source code of all the properties.

SocketErrorCode

SocketException.SocketErrorCode returns a value from the SocketError enum. The numerical values of the enum elements are the same on all the runtimes (see its implementation in .NET Framework, .NET Core 3.1.3, and Mono 6.8.0.105):

public enum SocketError
{
    SocketError = -1, // 0xFFFFFFFF
    Success = 0,
    OperationAborted = 995, // 0x000003E3
    IOPending = 997, // 0x000003E5
    Interrupted = 10004, // 0x00002714
    AccessDenied = 10013, // 0x0000271D
    Fault = 10014, // 0x0000271E
    InvalidArgument = 10022, // 0x00002726
    TooManyOpenSockets = 10024, // 0x00002728
    WouldBlock = 10035, // 0x00002733
    InProgress = 10036, // 0x00002734
    AlreadyInProgress = 10037, // 0x00002735
    NotSocket = 10038, // 0x00002736
    DestinationAddressRequired = 10039, // 0x00002737
    MessageSize = 10040, // 0x00002738
    ProtocolType = 10041, // 0x00002739
    ProtocolOption = 10042, // 0x0000273A
    ProtocolNotSupported = 10043, // 0x0000273B
    SocketNotSupported = 10044, // 0x0000273C
    OperationNotSupported = 10045, // 0x0000273D
    ProtocolFamilyNotSupported = 10046, // 0x0000273E
    AddressFamilyNotSupported = 10047, // 0x0000273F
    AddressAlreadyInUse = 10048, // 0x00002740
    AddressNotAvailable = 10049, // 0x00002741
    NetworkDown = 10050, // 0x00002742
    NetworkUnreachable = 10051, // 0x00002743
    NetworkReset = 10052, // 0x00002744
    ConnectionAborted = 10053, // 0x00002745
    ConnectionReset = 10054, // 0x00002746
    NoBufferSpaceAvailable = 10055, // 0x00002747
    IsConnected = 10056, // 0x00002748
    NotConnected = 10057, // 0x00002749
    Shutdown = 10058, // 0x0000274A
    TimedOut = 10060, // 0x0000274C
    ConnectionRefused = 10061, // 0x0000274D
    HostDown = 10064, // 0x00002750
    HostUnreachable = 10065, // 0x00002751
    ProcessLimit = 10067, // 0x00002753
    SystemNotReady = 10091, // 0x0000276B
    VersionNotSupported = 10092, // 0x0000276C
    NotInitialized = 10093, // 0x0000276D
    Disconnecting = 10101, // 0x00002775
    TypeNotFound = 10109, // 0x0000277D
    HostNotFound = 11001, // 0x00002AF9
    TryAgain = 11002, // 0x00002AFA
    NoRecovery = 11003, // 0x00002AFB
    NoData = 11004, // 0x00002AFC
}

These values correspond to the Windows Sockets Error Codes.

NativeErrorCode

In .NET Framework and Mono, SocketErrorCode and NativeErrorCode always have the same values:

public SocketError SocketErrorCode {
    //
    // the base class returns the HResult with this property
    // we need the Win32 Error Code, hence the override.
    //
    get {
        return (SocketError)NativeErrorCode;
    }
}

In .NET Core, the native code is calculated in the constructor (see SocketException.cs#L20):

public SocketException(int errorCode) : this((SocketError)errorCode)
// ...
internal SocketException(SocketError socketError) : base(GetNativeErrorForSocketError(socketError))

The Windows implementation of GetNativeErrorForSocketError is trivial (see SocketException.Windows.cs):

private static int GetNativeErrorForSocketError(SocketError error)
{
    // SocketError values map directly to Win32 error codes
    return (int)error;
}

The Unix implementation is more complicated (see SocketException.Unix.cs):

private static int GetNativeErrorForSocketError(SocketError error)
{
    int nativeErr = (int)error;
    if (error != SocketError.SocketError)
    {
        Interop.Error interopErr;

        // If an interop error was not found, then don't invoke Info().RawErrno as that will fail with assert.
        if (SocketErrorPal.TryGetNativeErrorForSocketError(error, out interopErr))
        {
            nativeErr = interopErr.Info().RawErrno;
        }
    }

    return nativeErr;
}

TryGetNativeErrorForSocketError should convert SocketError to the native Unix error code.
Unfortunately, there exists no unequivocal mapping between Windows and Unix error codes. As such, the .NET team decided to create a Dictionary that maps error codes in the best possible way (see SocketErrorPal.Unix.cs):

private const int NativeErrorToSocketErrorCount = 42;
private const int SocketErrorToNativeErrorCount = 40;

// No Interop.Errors are included for the following SocketErrors, as there's no good mapping:
// - SocketError.NoRecovery
// - SocketError.NotInitialized
// - SocketError.ProcessLimit
// - SocketError.SocketError
// - SocketError.SystemNotReady
// - SocketError.TypeNotFound
// - SocketError.VersionNotSupported

private static readonly Dictionary<Interop.Error, SocketError> s_nativeErrorToSocketError = new Dictionary<Interop.Error, SocketError>(NativeErrorToSocketErrorCount)
{
    { Interop.Error.EACCES, SocketError.AccessDenied },
    { Interop.Error.EADDRINUSE, SocketError.AddressAlreadyInUse },
    { Interop.Error.EADDRNOTAVAIL, SocketError.AddressNotAvailable },
    { Interop.Error.EAFNOSUPPORT, SocketError.AddressFamilyNotSupported },
    { Interop.Error.EAGAIN, SocketError.WouldBlock },
    { Interop.Error.EALREADY, SocketError.AlreadyInProgress },
    { Interop.Error.EBADF, SocketError.OperationAborted },
    { Interop.Error.ECANCELED, SocketError.OperationAborted },
    { Interop.Error.ECONNABORTED, SocketError.ConnectionAborted },
    { Interop.Error.ECONNREFUSED, SocketError.ConnectionRefused },
    { Interop.Error.ECONNRESET, SocketError.ConnectionReset },
    { Interop.Error.EDESTADDRREQ, SocketError.DestinationAddressRequired },
    { Interop.Error.EFAULT, SocketError.Fault },
    { Interop.Error.EHOSTDOWN, SocketError.HostDown },
    { Interop.Error.ENXIO, SocketError.HostNotFound }, // not perfect, but closest match available
    { Interop.Error.EHOSTUNREACH, SocketError.HostUnreachable },
    { Interop.Error.EINPROGRESS, SocketError.InProgress },
    { Interop.Error.EINTR, SocketError.Interrupted },
    { Interop.Error.EINVAL, SocketError.InvalidArgument },
    { Interop.Error.EISCONN, SocketError.IsConnected },
    { Interop.Error.EMFILE, SocketError.TooManyOpenSockets },
    { Interop.Error.EMSGSIZE, SocketError.MessageSize },
    { Interop.Error.ENETDOWN, SocketError.NetworkDown },
    { Interop.Error.ENETRESET, SocketError.NetworkReset },
    { Interop.Error.ENETUNREACH, SocketError.NetworkUnreachable },
    { Interop.Error.ENFILE, SocketError.TooManyOpenSockets },
    { Interop.Error.ENOBUFS, SocketError.NoBufferSpaceAvailable },
    { Interop.Error.ENODATA, SocketError.NoData },
    { Interop.Error.ENOENT, SocketError.AddressNotAvailable },
    { Interop.Error.ENOPROTOOPT, SocketError.ProtocolOption },
    { Interop.Error.ENOTCONN, SocketError.NotConnected },
    { Interop.Error.ENOTSOCK, SocketError.NotSocket },
    { Interop.Error.ENOTSUP, SocketError.OperationNotSupported },
    { Interop.Error.EPERM, SocketError.AccessDenied },
    { Interop.Error.EPIPE, SocketError.Shutdown },
    { Interop.Error.EPFNOSUPPORT, SocketError.ProtocolFamilyNotSupported },
    { Interop.Error.EPROTONOSUPPORT, SocketError.ProtocolNotSupported },
    { Interop.Error.EPROTOTYPE, SocketError.ProtocolType },
    { Interop.Error.ESOCKTNOSUPPORT, SocketError.SocketNotSupported },
    { Interop.Error.ESHUTDOWN, SocketError.Disconnecting },
    { Interop.Error.SUCCESS, SocketError.Success },
    { Interop.Error.ETIMEDOUT, SocketError.TimedOut },
};

private static readonly Dictionary<SocketError, Interop.Error> s_socketErrorToNativeError = new Dictionary<SocketError, Interop.Error>(SocketErrorToNativeErrorCount)
{
    // This is *mostly* an inverse mapping of s_nativeErrorToSocketError.  However, some options have multiple mappings and thus
    // can't be inverted directly.  Other options don't have a mapping from native to SocketError, but when presented with a SocketError,
    // we want to provide the closest relevant Error possible, e.g. EINPROGRESS maps to SocketError.InProgress, and vice versa, but
    // SocketError.IOPending also maps closest to EINPROGRESS.  As such, roundtripping won't necessarily provide the original value 100% of the time,
    // but it's the best we can do given the mismatch between Interop.Error and SocketError.

    { SocketError.AccessDenied, Interop.Error.EACCES}, // could also have been EPERM
    { SocketError.AddressAlreadyInUse, Interop.Error.EADDRINUSE  },
    { SocketError.AddressNotAvailable, Interop.Error.EADDRNOTAVAIL },
    { SocketError.AddressFamilyNotSupported, Interop.Error.EAFNOSUPPORT  },
    { SocketError.AlreadyInProgress, Interop.Error.EALREADY },
    { SocketError.ConnectionAborted, Interop.Error.ECONNABORTED },
    { SocketError.ConnectionRefused, Interop.Error.ECONNREFUSED },
    { SocketError.ConnectionReset, Interop.Error.ECONNRESET },
    { SocketError.DestinationAddressRequired, Interop.Error.EDESTADDRREQ },
    { SocketError.Disconnecting, Interop.Error.ESHUTDOWN },
    { SocketError.Fault, Interop.Error.EFAULT },
    { SocketError.HostDown, Interop.Error.EHOSTDOWN },
    { SocketError.HostNotFound, Interop.Error.EHOSTNOTFOUND },
    { SocketError.HostUnreachable, Interop.Error.EHOSTUNREACH },
    { SocketError.InProgress, Interop.Error.EINPROGRESS },
    { SocketError.Interrupted, Interop.Error.EINTR },
    { SocketError.InvalidArgument, Interop.Error.EINVAL },
    { SocketError.IOPending, Interop.Error.EINPROGRESS },
    { SocketError.IsConnected, Interop.Error.EISCONN },
    { SocketError.MessageSize, Interop.Error.EMSGSIZE },
    { SocketError.NetworkDown, Interop.Error.ENETDOWN },
    { SocketError.NetworkReset, Interop.Error.ENETRESET },
    { SocketError.NetworkUnreachable, Interop.Error.ENETUNREACH },
    { SocketError.NoBufferSpaceAvailable, Interop.Error.ENOBUFS },
    { SocketError.NoData, Interop.Error.ENODATA },
    { SocketError.NotConnected, Interop.Error.ENOTCONN },
    { SocketError.NotSocket, Interop.Error.ENOTSOCK },
    { SocketError.OperationAborted, Interop.Error.ECANCELED },
    { SocketError.OperationNotSupported, Interop.Error.ENOTSUP },
    { SocketError.ProtocolFamilyNotSupported, Interop.Error.EPFNOSUPPORT },
    { SocketError.ProtocolNotSupported, Interop.Error.EPROTONOSUPPORT },
    { SocketError.ProtocolOption, Interop.Error.ENOPROTOOPT },
    { SocketError.ProtocolType, Interop.Error.EPROTOTYPE },
    { SocketError.Shutdown, Interop.Error.EPIPE },
    { SocketError.SocketNotSupported, Interop.Error.ESOCKTNOSUPPORT },
    { SocketError.Success, Interop.Error.SUCCESS },
    { SocketError.TimedOut, Interop.Error.ETIMEDOUT },
    { SocketError.TooManyOpenSockets, Interop.Error.ENFILE }, // could also have been EMFILE
    { SocketError.TryAgain, Interop.Error.EAGAIN }, // not a perfect mapping, but better than nothing
    { SocketError.WouldBlock, Interop.Error.EAGAIN  },
};

internal static bool TryGetNativeErrorForSocketError(SocketError error, out Interop.Error errno)
{
    return s_socketErrorToNativeError.TryGetValue(error, out errno);
}

Once we have an instance of Interop.Error, we call interopErr.Info().RawErrno. The implementation of RawErrno can be found in Interop.Errors.cs:

internal int RawErrno
{
    get { return _rawErrno == -1 ? (_rawErrno = Interop.Sys.ConvertErrorPalToPlatform(_error)) : _rawErrno; }
}

[DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_ConvertErrorPalToPlatform")]
internal static extern int ConvertErrorPalToPlatform(Error error);

Here we are jumping to the native function SystemNative_ConvertErrorPalToPlatform that maps Error to the native integer code that is defined in errno.h. You can get all the values using the errno util. Here is a typical output on Linux:

$ errno -ls
EPERM 1 Operation not permitted
ENOENT 2 No such file or directory
ESRCH 3 No such process
EINTR 4 Interrupted system call
EIO 5 Input/output error
ENXIO 6 No such device or address
E2BIG 7 Argument list too long
ENOEXEC 8 Exec format error
EBADF 9 Bad file descriptor
ECHILD 10 No child processes
EAGAIN 11 Resource temporarily unavailable
ENOMEM 12 Cannot allocate memory
EACCES 13 Permission denied
EFAULT 14 Bad address
ENOTBLK 15 Block device required
EBUSY 16 Device or resource busy
EEXIST 17 File exists
EXDEV 18 Invalid cross-device link
ENODEV 19 No such device
ENOTDIR 20 Not a directory
EISDIR 21 Is a directory
EINVAL 22 Invalid argument
ENFILE 23 Too many open files in system
EMFILE 24 Too many open files
ENOTTY 25 Inappropriate ioctl for device
ETXTBSY 26 Text file busy
EFBIG 27 File too large
ENOSPC 28 No space left on device
ESPIPE 29 Illegal seek
EROFS 30 Read-only file system
EMLINK 31 Too many links
EPIPE 32 Broken pipe
EDOM 33 Numerical argument out of domain
ERANGE 34 Numerical result out of range
EDEADLK 35 Resource deadlock avoided
ENAMETOOLONG 36 File name too long
ENOLCK 37 No locks available
ENOSYS 38 Function not implemented
ENOTEMPTY 39 Directory not empty
ELOOP 40 Too many levels of symbolic links
EWOULDBLOCK 11 Resource temporarily unavailable
ENOMSG 42 No message of desired type
EIDRM 43 Identifier removed
ECHRNG 44 Channel number out of range
EL2NSYNC 45 Level 2 not synchronized
EL3HLT 46 Level 3 halted
EL3RST 47 Level 3 reset
ELNRNG 48 Link number out of range
EUNATCH 49 Protocol driver not attached
ENOCSI 50 No CSI structure available
EL2HLT 51 Level 2 halted
EBADE 52 Invalid exchange
EBADR 53 Invalid request descriptor
EXFULL 54 Exchange full
ENOANO 55 No anode
EBADRQC 56 Invalid request code
EBADSLT 57 Invalid slot
EDEADLOCK 35 Resource deadlock avoided
EBFONT 59 Bad font file format
ENOSTR 60 Device not a stream
ENODATA 61 No data available
ETIME 62 Timer expired
ENOSR 63 Out of streams resources
ENONET 64 Machine is not on the network
ENOPKG 65 Package not installed
EREMOTE 66 Object is remote
ENOLINK 67 Link has been severed
EADV 68 Advertise error
ESRMNT 69 Srmount error
ECOMM 70 Communication error on send
EPROTO 71 Protocol error
EMULTIHOP 72 Multihop attempted
EDOTDOT 73 RFS specific error
EBADMSG 74 Bad message
EOVERFLOW 75 Value too large for defined data type
ENOTUNIQ 76 Name not unique on network
EBADFD 77 File descriptor in bad state
EREMCHG 78 Remote address changed
ELIBACC 79 Can not access a needed shared library
ELIBBAD 80 Accessing a corrupted shared library
ELIBSCN 81 .lib section in a.out corrupted
ELIBMAX 82 Attempting to link in too many shared libraries
ELIBEXEC 83 Cannot exec a shared library directly
EILSEQ 84 Invalid or incomplete multibyte or wide character
ERESTART 85 Interrupted system call should be restarted
ESTRPIPE 86 Streams pipe error
EUSERS 87 Too many users
ENOTSOCK 88 Socket operation on non-socket
EDESTADDRREQ 89 Destination address required
EMSGSIZE 90 Message too long
EPROTOTYPE 91 Protocol wrong type for socket
ENOPROTOOPT 92 Protocol not available
EPROTONOSUPPORT 93 Protocol not supported
ESOCKTNOSUPPORT 94 Socket type not supported
EOPNOTSUPP 95 Operation not supported
EPFNOSUPPORT 96 Protocol family not supported
EAFNOSUPPORT 97 Address family not supported by protocol
EADDRINUSE 98 Address already in use
EADDRNOTAVAIL 99 Cannot assign requested address
ENETDOWN 100 Network is down
ENETUNREACH 101 Network is unreachable
ENETRESET 102 Network dropped connection on reset
ECONNABORTED 103 Software caused connection abort
ECONNRESET 104 Connection reset by peer
ENOBUFS 105 No buffer space available
EISCONN 106 Transport endpoint is already connected
ENOTCONN 107 Transport endpoint is not connected
ESHUTDOWN 108 Cannot send after transport endpoint shutdown
ETOOMANYREFS 109 Too many references: cannot splice
ETIMEDOUT 110 Connection timed out
ECONNREFUSED 111 Connection refused
EHOSTDOWN 112 Host is down
EHOSTUNREACH 113 No route to host
EALREADY 114 Operation already in progress
EINPROGRESS 115 Operation now in progress
ESTALE 116 Stale file handle
EUCLEAN 117 Structure needs cleaning
ENOTNAM 118 Not a XENIX named type file
ENAVAIL 119 No XENIX semaphores available
EISNAM 120 Is a named type file
EREMOTEIO 121 Remote I/O error
EDQUOT 122 Disk quota exceeded
ENOMEDIUM 123 No medium found
EMEDIUMTYPE 124 Wrong medium type
ECANCELED 125 Operation canceled
ENOKEY 126 Required key not available
EKEYEXPIRED 127 Key has expired
EKEYREVOKED 128 Key has been revoked
EKEYREJECTED 129 Key was rejected by service
EOWNERDEAD 130 Owner died
ENOTRECOVERABLE 131 State not recoverable
ERFKILL 132 Operation not possible due to RF-kill
EHWPOISON 133 Memory page has hardware error
ENOTSUP 95 Operation not supported

Note that errno may be not available by default in your Linux distro. For example, on Debian, you should call sudo apt-get install moreutils to get this utility.
Here is a typical output on macOS:

$ errno -ls
EPERM 1 Operation not permitted
ENOENT 2 No such file or directory
ESRCH 3 No such process
EINTR 4 Interrupted system call
EIO 5 Input/output error
ENXIO 6 Device not configured
E2BIG 7 Argument list too long
ENOEXEC 8 Exec format error
EBADF 9 Bad file descriptor
ECHILD 10 No child processes
EDEADLK 11 Resource deadlock avoided
ENOMEM 12 Cannot allocate memory
EACCES 13 Permission denied
EFAULT 14 Bad address
ENOTBLK 15 Block device required
EBUSY 16 Resource busy
EEXIST 17 File exists
EXDEV 18 Cross-device link
ENODEV 19 Operation not supported by device
ENOTDIR 20 Not a directory
EISDIR 21 Is a directory
EINVAL 22 Invalid argument
ENFILE 23 Too many open files in system
EMFILE 24 Too many open files
ENOTTY 25 Inappropriate ioctl for device
ETXTBSY 26 Text file busy
EFBIG 27 File too large
ENOSPC 28 No space left on device
ESPIPE 29 Illegal seek
EROFS 30 Read-only file system
EMLINK 31 Too many links
EPIPE 32 Broken pipe
EDOM 33 Numerical argument out of domain
ERANGE 34 Result too large
EAGAIN 35 Resource temporarily unavailable
EWOULDBLOCK 35 Resource temporarily unavailable
EINPROGRESS 36 Operation now in progress
EALREADY 37 Operation already in progress
ENOTSOCK 38 Socket operation on non-socket
EDESTADDRREQ 39 Destination address required
EMSGSIZE 40 Message too long
EPROTOTYPE 41 Protocol wrong type for socket
ENOPROTOOPT 42 Protocol not available
EPROTONOSUPPORT 43 Protocol not supported
ESOCKTNOSUPPORT 44 Socket type not supported
ENOTSUP 45 Operation not supported
EPFNOSUPPORT 46 Protocol family not supported
EAFNOSUPPORT 47 Address family not supported by protocol family
EADDRINUSE 48 Address already in use
EADDRNOTAVAIL 49 Can`t assign requested address
ENETDOWN 50 Network is down
ENETUNREACH 51 Network is unreachable
ENETRESET 52 Network dropped connection on reset
ECONNABORTED 53 Software caused connection abort
ECONNRESET 54 Connection reset by peer
ENOBUFS 55 No buffer space available
EISCONN 56 Socket is already connected
ENOTCONN 57 Socket is not connected
ESHUTDOWN 58 Can`t send after socket shutdown
ETOOMANYREFS 59 Too many references: can`t splice
ETIMEDOUT 60 Operation timed out
ECONNREFUSED 61 Connection refused
ELOOP 62 Too many levels of symbolic links
ENAMETOOLONG 63 File name too long
EHOSTDOWN 64 Host is down
EHOSTUNREACH 65 No route to host
ENOTEMPTY 66 Directory not empty
EPROCLIM 67 Too many processes
EUSERS 68 Too many users
EDQUOT 69 Disc quota exceeded
ESTALE 70 Stale NFS file handle
EREMOTE 71 Too many levels of remote in path
EBADRPC 72 RPC struct is bad
ERPCMISMATCH 73 RPC version wrong
EPROGUNAVAIL 74 RPC prog. not avail
EPROGMISMATCH 75 Program version wrong
EPROCUNAVAIL 76 Bad procedure for program
ENOLCK 77 No locks available
ENOSYS 78 Function not implemented
EFTYPE 79 Inappropriate file type or format
EAUTH 80 Authentication error
ENEEDAUTH 81 Need authenticator
EPWROFF 82 Device power is off
EDEVERR 83 Device error
EOVERFLOW 84 Value too large to be stored in data type
EBADEXEC 85 Bad executable (or shared library)
EBADARCH 86 Bad CPU type in executable
ESHLIBVERS 87 Shared library version mismatch
EBADMACHO 88 Malformed Mach-o file
ECANCELED 89 Operation canceled
EIDRM 90 Identifier removed
ENOMSG 91 No message of desired type
EILSEQ 92 Illegal byte sequence
ENOATTR 93 Attribute not found
EBADMSG 94 Bad message
EMULTIHOP 95 EMULTIHOP (Reserved)
ENODATA 96 No message available on STREAM
ENOLINK 97 ENOLINK (Reserved)
ENOSR 98 No STREAM resources
ENOSTR 99 Not a STREAM
EPROTO 100 Protocol error
ETIME 101 STREAM ioctl timeout
EOPNOTSUPP 102 Operation not supported on socket
ENOPOLICY 103 Policy not found
ENOTRECOVERABLE 104 State not recoverable
EOWNERDEAD 105 Previous owner died
EQFULL 106 Interface output queue is full
ELAST 106 Interface output queue is full

Hooray! We’ve finished our fascinating journey into the internals of socket error codes. Now you know where .NET is getting the native error code for each SocketException from!

ErrorCode

The ErrorCode property is the most boring one, as it always returns NativeErrorCode.
.NET Framework, Mono 6.8.0.105:

public override int ErrorCode {
    //
    // the base class returns the HResult with this property
    // we need the Win32 Error Code, hence the override.
    //
    get {
        return NativeErrorCode;
    }
}

In .NET Core 3.1.3:

public override int ErrorCode => base.NativeErrorCode;

Writing cross-platform socket error handling

Circling back to the original method we started this post with, we rewrote ShouldRetryConnection as follows:

protected virtual bool ShouldRetryConnection(Exception ex)
{
    if (ex is SocketException sx)
        return sx.SocketErrorCode == SocketError.ConnectionRefused;
    return false;
}

There was a lot of work involved in tracking down the error code to check against, but in the end, our code is much more readable now. Adding to that, this method is now also completely cross-platform, and works correctly on any runtime.

Overview of the native error codes

In some situations, you may want to have a table with native error codes on different operating systems. We can get these values with the following code snippet:

var allErrors = Enum.GetValues(typeof(SocketError)).Cast<SocketError>().ToList();
var maxNameWidth = allErrors.Select(x => x.ToString().Length).Max();
foreach (var socketError in allErrors)
{
    var name = socketError.ToString().PadRight(maxNameWidth);
    var code = new SocketException((int) socketError).NativeErrorCode.ToString().PadLeft(7);
    Console.WriteLine("| {name} | {code} |");
}

We executed this program on Windows, Linux, and macOS. Here are the aggregated results:

SocketError Windows Linux macOS
Success 0 0 0
OperationAborted 995 125 89
IOPending 997 115 36
Interrupted 10004 4 4
AccessDenied 10013 13 13
Fault 10014 14 14
InvalidArgument 10022 22 22
TooManyOpenSockets 10024 23 23
WouldBlock 10035 11 35
InProgress 10036 115 36
AlreadyInProgress 10037 114 37
NotSocket 10038 88 38
DestinationAddressRequired 10039 89 39
MessageSize 10040 90 40
ProtocolType 10041 91 41
ProtocolOption 10042 92 42
ProtocolNotSupported 10043 93 43
SocketNotSupported 10044 94 44
OperationNotSupported 10045 95 45
ProtocolFamilyNotSupported 10046 96 46
AddressFamilyNotSupported 10047 97 47
AddressAlreadyInUse 10048 98 48
AddressNotAvailable 10049 99 49
NetworkDown 10050 100 50
NetworkUnreachable 10051 101 51
NetworkReset 10052 102 52
ConnectionAborted 10053 103 53
ConnectionReset 10054 104 54
NoBufferSpaceAvailable 10055 105 55
IsConnected 10056 106 56
NotConnected 10057 107 57
Shutdown 10058 32 32
TimedOut 10060 110 60
ConnectionRefused 10061 111 61
HostDown 10064 112 64
HostUnreachable 10065 113 65
ProcessLimit 10067 10067 10067
SystemNotReady 10091 10091 10091
VersionNotSupported 10092 10092 10092
NotInitialized 10093 10093 10093
Disconnecting 10101 108 58
TypeNotFound 10109 10109 10109
HostNotFound 11001 -131073 -131073
TryAgain 11002 11 35
NoRecovery 11003 11003 11003
NoData 11004 61 96
SocketError -1 -1 -1

This table may be useful if you work with native socket error codes.

Summary

From this investigation, we’ve learned the following:

  • SocketException.SocketErrorCode returns a value from the SocketError enum. The numerical values of the enum elements always correspond to the Windows socket error codes.
  • SocketException.ErrorCode always returns SocketException.NativeErrorCode.
  • SocketException.NativeErrorCode on .NET Framework and Mono always corresponds to the Windows error codes (even if you are using Mono on Unix). On .NET Core, SocketException.NativeErrorCode equals the corresponding native error code from the current operating system.

A few practical recommendations:

  • If you want to write portable code, always use SocketException.SocketErrorCode and compare it with the values of SocketError. Never use raw numerical error codes.
  • If you want to get the native error code on .NET Core (e.g., for passing to another native program), use SocketException.NativeErrorCode. Remember that different Unix-based operating systems (e.g., Linux, macOS, Solaris) have different native code sets. You can get the exact values of the native error codes by using the errno command.

References

  • Microsoft Docs: Windows Sockets Error Codes
  • IBM Knowledge Center: TCP/IP error codes
  • MariaDB: Operating System Error Codes
  • gnu.org: Error Codes
  • Stackoverflow: Identical Error Codes

Dotnet logo

Dev Team blog

How Socket Error Codes Depend on Runtime and Operating System

This post is the first part of a blog post series that covers different technical challenges that we had to resolve during the migration of the Rider backend process from Mono to .NET Core. By sharing our experiences, we hope to help out those who are in the same boat.
There’s too much to share in one post, so we will make this into a series of posts. In this series:

  • How Socket Error Codes Depend on Runtime and Operating System
  • How Sorting Order Depends on Runtime and Operating System
  • How ListSeparator Depends on Runtime and Operating System

Let’s dive in!

Sockets and error codes

Rider consists of several processes that send messages to each other via sockets. To ensure the reliability of the whole application, it’s important to properly handle all the socket errors. In our codebase, we had the following code which was adopted from Mono Debugger Libs and helps us communicate with debugger processes:

protected virtual bool ShouldRetryConnection (Exception ex, int attemptNumber)
{
    var sx = ex as SocketException;
    if (sx != null) {
        if (sx.ErrorCode == 10061) //connection refused
            return true;
    }
    return false;
}

In the case of a failed connection because of a “ConnectionRefused” error, we are retrying the connection attempt. It works fine with .NET Framework and Mono. However, once we migrated to .NET Core, this method no longer correctly detects the “connection refused” situation on Linux and macOS. If we open the SocketException documentation, we will learn that this class has three different properties with error codes:

  • SocketError SocketErrorCode: Gets the error code that is associated with this exception.
  • int ErrorCode: Gets the error code that is associated with this exception.
  • int NativeErrorCode: Gets the Win32 error code associated with this exception.

What’s the difference between these properties? Should we expect different values on different runtimes or different operating systems? Which one should we use in production? Why do we have problems with ShouldRetryConnection on .NET Core? Let’s figure it all out!

Digging into the problem

Let’s start with the following program, which prints error code property values for SocketError.ConnectionRefused:

var se = new SocketException((int) SocketError.ConnectionRefused);
Console.WriteLine((int)se.SocketErrorCode);
Console.WriteLine(se.ErrorCode);
Console.WriteLine(se.NativeErrorCode);

If we run it on Windows, we will get the same value on .NET Framework, Mono, and .NET Core:

SocketErrorCode ErrorCode NativeErrorCode
.NET Framework 10061 10061 10061
Mono 10061 10061 10061
.NET Core 10061 10061 10061

10061 corresponds to the code of the connection refused socket error code in Windows (also known as WSAECONNREFUSED).
Now let’s run the same program on Linux:

SocketErrorCode ErrorCode NativeErrorCode
Mono 10061 10061 10061
.NET Core 10061 111 111

As you can see, Mono returns Windows-compatible error codes. The situation with .NET Core is different: it returns a Windows-compatible value for SocketErrorCode (10061) and a Linux-like value for ErrorCode and NativeErrorCode (111).
Finally, let’s check macOS:

SocketErrorCode ErrorCode NativeErrorCode
Mono 10061 10061 10061
.NET Core 10061 61 61

Here, Mono is completely Windows-compatible again, but .NET Core returns 61 for ErrorCode and NativeErrorCode.
In the IBM Knowledge Center, we can find a few more values for the connection refused error code from the Unix world (also known as ECONNREFUSED):

  • AIX: 79
  • HP-UX: 239
  • Solaris: 146

For a better understanding of what’s going on, let’s check out the source code of all the properties.

SocketErrorCode

SocketException.SocketErrorCode returns a value from the SocketError enum. The numerical values of the enum elements are the same on all the runtimes (see its implementation in .NET Framework, .NET Core 3.1.3, and Mono 6.8.0.105):

public enum SocketError
{
    SocketError = -1, // 0xFFFFFFFF
    Success = 0,
    OperationAborted = 995, // 0x000003E3
    IOPending = 997, // 0x000003E5
    Interrupted = 10004, // 0x00002714
    AccessDenied = 10013, // 0x0000271D
    Fault = 10014, // 0x0000271E
    InvalidArgument = 10022, // 0x00002726
    TooManyOpenSockets = 10024, // 0x00002728
    WouldBlock = 10035, // 0x00002733
    InProgress = 10036, // 0x00002734
    AlreadyInProgress = 10037, // 0x00002735
    NotSocket = 10038, // 0x00002736
    DestinationAddressRequired = 10039, // 0x00002737
    MessageSize = 10040, // 0x00002738
    ProtocolType = 10041, // 0x00002739
    ProtocolOption = 10042, // 0x0000273A
    ProtocolNotSupported = 10043, // 0x0000273B
    SocketNotSupported = 10044, // 0x0000273C
    OperationNotSupported = 10045, // 0x0000273D
    ProtocolFamilyNotSupported = 10046, // 0x0000273E
    AddressFamilyNotSupported = 10047, // 0x0000273F
    AddressAlreadyInUse = 10048, // 0x00002740
    AddressNotAvailable = 10049, // 0x00002741
    NetworkDown = 10050, // 0x00002742
    NetworkUnreachable = 10051, // 0x00002743
    NetworkReset = 10052, // 0x00002744
    ConnectionAborted = 10053, // 0x00002745
    ConnectionReset = 10054, // 0x00002746
    NoBufferSpaceAvailable = 10055, // 0x00002747
    IsConnected = 10056, // 0x00002748
    NotConnected = 10057, // 0x00002749
    Shutdown = 10058, // 0x0000274A
    TimedOut = 10060, // 0x0000274C
    ConnectionRefused = 10061, // 0x0000274D
    HostDown = 10064, // 0x00002750
    HostUnreachable = 10065, // 0x00002751
    ProcessLimit = 10067, // 0x00002753
    SystemNotReady = 10091, // 0x0000276B
    VersionNotSupported = 10092, // 0x0000276C
    NotInitialized = 10093, // 0x0000276D
    Disconnecting = 10101, // 0x00002775
    TypeNotFound = 10109, // 0x0000277D
    HostNotFound = 11001, // 0x00002AF9
    TryAgain = 11002, // 0x00002AFA
    NoRecovery = 11003, // 0x00002AFB
    NoData = 11004, // 0x00002AFC
}

These values correspond to the Windows Sockets Error Codes.

NativeErrorCode

In .NET Framework and Mono, SocketErrorCode and NativeErrorCode always have the same values:

public SocketError SocketErrorCode {
    //
    // the base class returns the HResult with this property
    // we need the Win32 Error Code, hence the override.
    //
    get {
        return (SocketError)NativeErrorCode;
    }
}

In .NET Core, the native code is calculated in the constructor (see SocketException.cs#L20):

public SocketException(int errorCode) : this((SocketError)errorCode)
// ...
internal SocketException(SocketError socketError) : base(GetNativeErrorForSocketError(socketError))

The Windows implementation of GetNativeErrorForSocketError is trivial (see SocketException.Windows.cs):

private static int GetNativeErrorForSocketError(SocketError error)
{
    // SocketError values map directly to Win32 error codes
    return (int)error;
}

The Unix implementation is more complicated (see SocketException.Unix.cs):

private static int GetNativeErrorForSocketError(SocketError error)
{
    int nativeErr = (int)error;
    if (error != SocketError.SocketError)
    {
        Interop.Error interopErr;

        // If an interop error was not found, then don't invoke Info().RawErrno as that will fail with assert.
        if (SocketErrorPal.TryGetNativeErrorForSocketError(error, out interopErr))
        {
            nativeErr = interopErr.Info().RawErrno;
        }
    }

    return nativeErr;
}

TryGetNativeErrorForSocketError should convert SocketError to the native Unix error code.
Unfortunately, there exists no unequivocal mapping between Windows and Unix error codes. As such, the .NET team decided to create a Dictionary that maps error codes in the best possible way (see SocketErrorPal.Unix.cs):

private const int NativeErrorToSocketErrorCount = 42;
private const int SocketErrorToNativeErrorCount = 40;

// No Interop.Errors are included for the following SocketErrors, as there's no good mapping:
// - SocketError.NoRecovery
// - SocketError.NotInitialized
// - SocketError.ProcessLimit
// - SocketError.SocketError
// - SocketError.SystemNotReady
// - SocketError.TypeNotFound
// - SocketError.VersionNotSupported

private static readonly Dictionary<Interop.Error, SocketError> s_nativeErrorToSocketError = new Dictionary<Interop.Error, SocketError>(NativeErrorToSocketErrorCount)
{
    { Interop.Error.EACCES, SocketError.AccessDenied },
    { Interop.Error.EADDRINUSE, SocketError.AddressAlreadyInUse },
    { Interop.Error.EADDRNOTAVAIL, SocketError.AddressNotAvailable },
    { Interop.Error.EAFNOSUPPORT, SocketError.AddressFamilyNotSupported },
    { Interop.Error.EAGAIN, SocketError.WouldBlock },
    { Interop.Error.EALREADY, SocketError.AlreadyInProgress },
    { Interop.Error.EBADF, SocketError.OperationAborted },
    { Interop.Error.ECANCELED, SocketError.OperationAborted },
    { Interop.Error.ECONNABORTED, SocketError.ConnectionAborted },
    { Interop.Error.ECONNREFUSED, SocketError.ConnectionRefused },
    { Interop.Error.ECONNRESET, SocketError.ConnectionReset },
    { Interop.Error.EDESTADDRREQ, SocketError.DestinationAddressRequired },
    { Interop.Error.EFAULT, SocketError.Fault },
    { Interop.Error.EHOSTDOWN, SocketError.HostDown },
    { Interop.Error.ENXIO, SocketError.HostNotFound }, // not perfect, but closest match available
    { Interop.Error.EHOSTUNREACH, SocketError.HostUnreachable },
    { Interop.Error.EINPROGRESS, SocketError.InProgress },
    { Interop.Error.EINTR, SocketError.Interrupted },
    { Interop.Error.EINVAL, SocketError.InvalidArgument },
    { Interop.Error.EISCONN, SocketError.IsConnected },
    { Interop.Error.EMFILE, SocketError.TooManyOpenSockets },
    { Interop.Error.EMSGSIZE, SocketError.MessageSize },
    { Interop.Error.ENETDOWN, SocketError.NetworkDown },
    { Interop.Error.ENETRESET, SocketError.NetworkReset },
    { Interop.Error.ENETUNREACH, SocketError.NetworkUnreachable },
    { Interop.Error.ENFILE, SocketError.TooManyOpenSockets },
    { Interop.Error.ENOBUFS, SocketError.NoBufferSpaceAvailable },
    { Interop.Error.ENODATA, SocketError.NoData },
    { Interop.Error.ENOENT, SocketError.AddressNotAvailable },
    { Interop.Error.ENOPROTOOPT, SocketError.ProtocolOption },
    { Interop.Error.ENOTCONN, SocketError.NotConnected },
    { Interop.Error.ENOTSOCK, SocketError.NotSocket },
    { Interop.Error.ENOTSUP, SocketError.OperationNotSupported },
    { Interop.Error.EPERM, SocketError.AccessDenied },
    { Interop.Error.EPIPE, SocketError.Shutdown },
    { Interop.Error.EPFNOSUPPORT, SocketError.ProtocolFamilyNotSupported },
    { Interop.Error.EPROTONOSUPPORT, SocketError.ProtocolNotSupported },
    { Interop.Error.EPROTOTYPE, SocketError.ProtocolType },
    { Interop.Error.ESOCKTNOSUPPORT, SocketError.SocketNotSupported },
    { Interop.Error.ESHUTDOWN, SocketError.Disconnecting },
    { Interop.Error.SUCCESS, SocketError.Success },
    { Interop.Error.ETIMEDOUT, SocketError.TimedOut },
};

private static readonly Dictionary<SocketError, Interop.Error> s_socketErrorToNativeError = new Dictionary<SocketError, Interop.Error>(SocketErrorToNativeErrorCount)
{
    // This is *mostly* an inverse mapping of s_nativeErrorToSocketError.  However, some options have multiple mappings and thus
    // can't be inverted directly.  Other options don't have a mapping from native to SocketError, but when presented with a SocketError,
    // we want to provide the closest relevant Error possible, e.g. EINPROGRESS maps to SocketError.InProgress, and vice versa, but
    // SocketError.IOPending also maps closest to EINPROGRESS.  As such, roundtripping won't necessarily provide the original value 100% of the time,
    // but it's the best we can do given the mismatch between Interop.Error and SocketError.

    { SocketError.AccessDenied, Interop.Error.EACCES}, // could also have been EPERM
    { SocketError.AddressAlreadyInUse, Interop.Error.EADDRINUSE  },
    { SocketError.AddressNotAvailable, Interop.Error.EADDRNOTAVAIL },
    { SocketError.AddressFamilyNotSupported, Interop.Error.EAFNOSUPPORT  },
    { SocketError.AlreadyInProgress, Interop.Error.EALREADY },
    { SocketError.ConnectionAborted, Interop.Error.ECONNABORTED },
    { SocketError.ConnectionRefused, Interop.Error.ECONNREFUSED },
    { SocketError.ConnectionReset, Interop.Error.ECONNRESET },
    { SocketError.DestinationAddressRequired, Interop.Error.EDESTADDRREQ },
    { SocketError.Disconnecting, Interop.Error.ESHUTDOWN },
    { SocketError.Fault, Interop.Error.EFAULT },
    { SocketError.HostDown, Interop.Error.EHOSTDOWN },
    { SocketError.HostNotFound, Interop.Error.EHOSTNOTFOUND },
    { SocketError.HostUnreachable, Interop.Error.EHOSTUNREACH },
    { SocketError.InProgress, Interop.Error.EINPROGRESS },
    { SocketError.Interrupted, Interop.Error.EINTR },
    { SocketError.InvalidArgument, Interop.Error.EINVAL },
    { SocketError.IOPending, Interop.Error.EINPROGRESS },
    { SocketError.IsConnected, Interop.Error.EISCONN },
    { SocketError.MessageSize, Interop.Error.EMSGSIZE },
    { SocketError.NetworkDown, Interop.Error.ENETDOWN },
    { SocketError.NetworkReset, Interop.Error.ENETRESET },
    { SocketError.NetworkUnreachable, Interop.Error.ENETUNREACH },
    { SocketError.NoBufferSpaceAvailable, Interop.Error.ENOBUFS },
    { SocketError.NoData, Interop.Error.ENODATA },
    { SocketError.NotConnected, Interop.Error.ENOTCONN },
    { SocketError.NotSocket, Interop.Error.ENOTSOCK },
    { SocketError.OperationAborted, Interop.Error.ECANCELED },
    { SocketError.OperationNotSupported, Interop.Error.ENOTSUP },
    { SocketError.ProtocolFamilyNotSupported, Interop.Error.EPFNOSUPPORT },
    { SocketError.ProtocolNotSupported, Interop.Error.EPROTONOSUPPORT },
    { SocketError.ProtocolOption, Interop.Error.ENOPROTOOPT },
    { SocketError.ProtocolType, Interop.Error.EPROTOTYPE },
    { SocketError.Shutdown, Interop.Error.EPIPE },
    { SocketError.SocketNotSupported, Interop.Error.ESOCKTNOSUPPORT },
    { SocketError.Success, Interop.Error.SUCCESS },
    { SocketError.TimedOut, Interop.Error.ETIMEDOUT },
    { SocketError.TooManyOpenSockets, Interop.Error.ENFILE }, // could also have been EMFILE
    { SocketError.TryAgain, Interop.Error.EAGAIN }, // not a perfect mapping, but better than nothing
    { SocketError.WouldBlock, Interop.Error.EAGAIN  },
};

internal static bool TryGetNativeErrorForSocketError(SocketError error, out Interop.Error errno)
{
    return s_socketErrorToNativeError.TryGetValue(error, out errno);
}

Once we have an instance of Interop.Error, we call interopErr.Info().RawErrno. The implementation of RawErrno can be found in Interop.Errors.cs:

internal int RawErrno
{
    get { return _rawErrno == -1 ? (_rawErrno = Interop.Sys.ConvertErrorPalToPlatform(_error)) : _rawErrno; }
}

[DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_ConvertErrorPalToPlatform")]
internal static extern int ConvertErrorPalToPlatform(Error error);

Here we are jumping to the native function SystemNative_ConvertErrorPalToPlatform that maps Error to the native integer code that is defined in errno.h. You can get all the values using the errno util. Here is a typical output on Linux:

$ errno -ls
EPERM 1 Operation not permitted
ENOENT 2 No such file or directory
ESRCH 3 No such process
EINTR 4 Interrupted system call
EIO 5 Input/output error
ENXIO 6 No such device or address
E2BIG 7 Argument list too long
ENOEXEC 8 Exec format error
EBADF 9 Bad file descriptor
ECHILD 10 No child processes
EAGAIN 11 Resource temporarily unavailable
ENOMEM 12 Cannot allocate memory
EACCES 13 Permission denied
EFAULT 14 Bad address
ENOTBLK 15 Block device required
EBUSY 16 Device or resource busy
EEXIST 17 File exists
EXDEV 18 Invalid cross-device link
ENODEV 19 No such device
ENOTDIR 20 Not a directory
EISDIR 21 Is a directory
EINVAL 22 Invalid argument
ENFILE 23 Too many open files in system
EMFILE 24 Too many open files
ENOTTY 25 Inappropriate ioctl for device
ETXTBSY 26 Text file busy
EFBIG 27 File too large
ENOSPC 28 No space left on device
ESPIPE 29 Illegal seek
EROFS 30 Read-only file system
EMLINK 31 Too many links
EPIPE 32 Broken pipe
EDOM 33 Numerical argument out of domain
ERANGE 34 Numerical result out of range
EDEADLK 35 Resource deadlock avoided
ENAMETOOLONG 36 File name too long
ENOLCK 37 No locks available
ENOSYS 38 Function not implemented
ENOTEMPTY 39 Directory not empty
ELOOP 40 Too many levels of symbolic links
EWOULDBLOCK 11 Resource temporarily unavailable
ENOMSG 42 No message of desired type
EIDRM 43 Identifier removed
ECHRNG 44 Channel number out of range
EL2NSYNC 45 Level 2 not synchronized
EL3HLT 46 Level 3 halted
EL3RST 47 Level 3 reset
ELNRNG 48 Link number out of range
EUNATCH 49 Protocol driver not attached
ENOCSI 50 No CSI structure available
EL2HLT 51 Level 2 halted
EBADE 52 Invalid exchange
EBADR 53 Invalid request descriptor
EXFULL 54 Exchange full
ENOANO 55 No anode
EBADRQC 56 Invalid request code
EBADSLT 57 Invalid slot
EDEADLOCK 35 Resource deadlock avoided
EBFONT 59 Bad font file format
ENOSTR 60 Device not a stream
ENODATA 61 No data available
ETIME 62 Timer expired
ENOSR 63 Out of streams resources
ENONET 64 Machine is not on the network
ENOPKG 65 Package not installed
EREMOTE 66 Object is remote
ENOLINK 67 Link has been severed
EADV 68 Advertise error
ESRMNT 69 Srmount error
ECOMM 70 Communication error on send
EPROTO 71 Protocol error
EMULTIHOP 72 Multihop attempted
EDOTDOT 73 RFS specific error
EBADMSG 74 Bad message
EOVERFLOW 75 Value too large for defined data type
ENOTUNIQ 76 Name not unique on network
EBADFD 77 File descriptor in bad state
EREMCHG 78 Remote address changed
ELIBACC 79 Can not access a needed shared library
ELIBBAD 80 Accessing a corrupted shared library
ELIBSCN 81 .lib section in a.out corrupted
ELIBMAX 82 Attempting to link in too many shared libraries
ELIBEXEC 83 Cannot exec a shared library directly
EILSEQ 84 Invalid or incomplete multibyte or wide character
ERESTART 85 Interrupted system call should be restarted
ESTRPIPE 86 Streams pipe error
EUSERS 87 Too many users
ENOTSOCK 88 Socket operation on non-socket
EDESTADDRREQ 89 Destination address required
EMSGSIZE 90 Message too long
EPROTOTYPE 91 Protocol wrong type for socket
ENOPROTOOPT 92 Protocol not available
EPROTONOSUPPORT 93 Protocol not supported
ESOCKTNOSUPPORT 94 Socket type not supported
EOPNOTSUPP 95 Operation not supported
EPFNOSUPPORT 96 Protocol family not supported
EAFNOSUPPORT 97 Address family not supported by protocol
EADDRINUSE 98 Address already in use
EADDRNOTAVAIL 99 Cannot assign requested address
ENETDOWN 100 Network is down
ENETUNREACH 101 Network is unreachable
ENETRESET 102 Network dropped connection on reset
ECONNABORTED 103 Software caused connection abort
ECONNRESET 104 Connection reset by peer
ENOBUFS 105 No buffer space available
EISCONN 106 Transport endpoint is already connected
ENOTCONN 107 Transport endpoint is not connected
ESHUTDOWN 108 Cannot send after transport endpoint shutdown
ETOOMANYREFS 109 Too many references: cannot splice
ETIMEDOUT 110 Connection timed out
ECONNREFUSED 111 Connection refused
EHOSTDOWN 112 Host is down
EHOSTUNREACH 113 No route to host
EALREADY 114 Operation already in progress
EINPROGRESS 115 Operation now in progress
ESTALE 116 Stale file handle
EUCLEAN 117 Structure needs cleaning
ENOTNAM 118 Not a XENIX named type file
ENAVAIL 119 No XENIX semaphores available
EISNAM 120 Is a named type file
EREMOTEIO 121 Remote I/O error
EDQUOT 122 Disk quota exceeded
ENOMEDIUM 123 No medium found
EMEDIUMTYPE 124 Wrong medium type
ECANCELED 125 Operation canceled
ENOKEY 126 Required key not available
EKEYEXPIRED 127 Key has expired
EKEYREVOKED 128 Key has been revoked
EKEYREJECTED 129 Key was rejected by service
EOWNERDEAD 130 Owner died
ENOTRECOVERABLE 131 State not recoverable
ERFKILL 132 Operation not possible due to RF-kill
EHWPOISON 133 Memory page has hardware error
ENOTSUP 95 Operation not supported

Note that errno may be not available by default in your Linux distro. For example, on Debian, you should call sudo apt-get install moreutils to get this utility.
Here is a typical output on macOS:

$ errno -ls
EPERM 1 Operation not permitted
ENOENT 2 No such file or directory
ESRCH 3 No such process
EINTR 4 Interrupted system call
EIO 5 Input/output error
ENXIO 6 Device not configured
E2BIG 7 Argument list too long
ENOEXEC 8 Exec format error
EBADF 9 Bad file descriptor
ECHILD 10 No child processes
EDEADLK 11 Resource deadlock avoided
ENOMEM 12 Cannot allocate memory
EACCES 13 Permission denied
EFAULT 14 Bad address
ENOTBLK 15 Block device required
EBUSY 16 Resource busy
EEXIST 17 File exists
EXDEV 18 Cross-device link
ENODEV 19 Operation not supported by device
ENOTDIR 20 Not a directory
EISDIR 21 Is a directory
EINVAL 22 Invalid argument
ENFILE 23 Too many open files in system
EMFILE 24 Too many open files
ENOTTY 25 Inappropriate ioctl for device
ETXTBSY 26 Text file busy
EFBIG 27 File too large
ENOSPC 28 No space left on device
ESPIPE 29 Illegal seek
EROFS 30 Read-only file system
EMLINK 31 Too many links
EPIPE 32 Broken pipe
EDOM 33 Numerical argument out of domain
ERANGE 34 Result too large
EAGAIN 35 Resource temporarily unavailable
EWOULDBLOCK 35 Resource temporarily unavailable
EINPROGRESS 36 Operation now in progress
EALREADY 37 Operation already in progress
ENOTSOCK 38 Socket operation on non-socket
EDESTADDRREQ 39 Destination address required
EMSGSIZE 40 Message too long
EPROTOTYPE 41 Protocol wrong type for socket
ENOPROTOOPT 42 Protocol not available
EPROTONOSUPPORT 43 Protocol not supported
ESOCKTNOSUPPORT 44 Socket type not supported
ENOTSUP 45 Operation not supported
EPFNOSUPPORT 46 Protocol family not supported
EAFNOSUPPORT 47 Address family not supported by protocol family
EADDRINUSE 48 Address already in use
EADDRNOTAVAIL 49 Can`t assign requested address
ENETDOWN 50 Network is down
ENETUNREACH 51 Network is unreachable
ENETRESET 52 Network dropped connection on reset
ECONNABORTED 53 Software caused connection abort
ECONNRESET 54 Connection reset by peer
ENOBUFS 55 No buffer space available
EISCONN 56 Socket is already connected
ENOTCONN 57 Socket is not connected
ESHUTDOWN 58 Can`t send after socket shutdown
ETOOMANYREFS 59 Too many references: can`t splice
ETIMEDOUT 60 Operation timed out
ECONNREFUSED 61 Connection refused
ELOOP 62 Too many levels of symbolic links
ENAMETOOLONG 63 File name too long
EHOSTDOWN 64 Host is down
EHOSTUNREACH 65 No route to host
ENOTEMPTY 66 Directory not empty
EPROCLIM 67 Too many processes
EUSERS 68 Too many users
EDQUOT 69 Disc quota exceeded
ESTALE 70 Stale NFS file handle
EREMOTE 71 Too many levels of remote in path
EBADRPC 72 RPC struct is bad
ERPCMISMATCH 73 RPC version wrong
EPROGUNAVAIL 74 RPC prog. not avail
EPROGMISMATCH 75 Program version wrong
EPROCUNAVAIL 76 Bad procedure for program
ENOLCK 77 No locks available
ENOSYS 78 Function not implemented
EFTYPE 79 Inappropriate file type or format
EAUTH 80 Authentication error
ENEEDAUTH 81 Need authenticator
EPWROFF 82 Device power is off
EDEVERR 83 Device error
EOVERFLOW 84 Value too large to be stored in data type
EBADEXEC 85 Bad executable (or shared library)
EBADARCH 86 Bad CPU type in executable
ESHLIBVERS 87 Shared library version mismatch
EBADMACHO 88 Malformed Mach-o file
ECANCELED 89 Operation canceled
EIDRM 90 Identifier removed
ENOMSG 91 No message of desired type
EILSEQ 92 Illegal byte sequence
ENOATTR 93 Attribute not found
EBADMSG 94 Bad message
EMULTIHOP 95 EMULTIHOP (Reserved)
ENODATA 96 No message available on STREAM
ENOLINK 97 ENOLINK (Reserved)
ENOSR 98 No STREAM resources
ENOSTR 99 Not a STREAM
EPROTO 100 Protocol error
ETIME 101 STREAM ioctl timeout
EOPNOTSUPP 102 Operation not supported on socket
ENOPOLICY 103 Policy not found
ENOTRECOVERABLE 104 State not recoverable
EOWNERDEAD 105 Previous owner died
EQFULL 106 Interface output queue is full
ELAST 106 Interface output queue is full

Hooray! We’ve finished our fascinating journey into the internals of socket error codes. Now you know where .NET is getting the native error code for each SocketException from!

ErrorCode

The ErrorCode property is the most boring one, as it always returns NativeErrorCode.
.NET Framework, Mono 6.8.0.105:

public override int ErrorCode {
    //
    // the base class returns the HResult with this property
    // we need the Win32 Error Code, hence the override.
    //
    get {
        return NativeErrorCode;
    }
}

In .NET Core 3.1.3:

public override int ErrorCode => base.NativeErrorCode;

Writing cross-platform socket error handling

Circling back to the original method we started this post with, we rewrote ShouldRetryConnection as follows:

protected virtual bool ShouldRetryConnection(Exception ex)
{
    if (ex is SocketException sx)
        return sx.SocketErrorCode == SocketError.ConnectionRefused;
    return false;
}

There was a lot of work involved in tracking down the error code to check against, but in the end, our code is much more readable now. Adding to that, this method is now also completely cross-platform, and works correctly on any runtime.

Overview of the native error codes

In some situations, you may want to have a table with native error codes on different operating systems. We can get these values with the following code snippet:

var allErrors = Enum.GetValues(typeof(SocketError)).Cast<SocketError>().ToList();
var maxNameWidth = allErrors.Select(x => x.ToString().Length).Max();
foreach (var socketError in allErrors)
{
    var name = socketError.ToString().PadRight(maxNameWidth);
    var code = new SocketException((int) socketError).NativeErrorCode.ToString().PadLeft(7);
    Console.WriteLine($TEXT$quot;| {name} | {code} |");
}

We executed this program on Windows, Linux, and macOS. Here are the aggregated results:

SocketError Windows Linux macOS
Success 0 0 0
OperationAborted 995 125 89
IOPending 997 115 36
Interrupted 10004 4 4
AccessDenied 10013 13 13
Fault 10014 14 14
InvalidArgument 10022 22 22
TooManyOpenSockets 10024 23 23
WouldBlock 10035 11 35
InProgress 10036 115 36
AlreadyInProgress 10037 114 37
NotSocket 10038 88 38
DestinationAddressRequired 10039 89 39
MessageSize 10040 90 40
ProtocolType 10041 91 41
ProtocolOption 10042 92 42
ProtocolNotSupported 10043 93 43
SocketNotSupported 10044 94 44
OperationNotSupported 10045 95 45
ProtocolFamilyNotSupported 10046 96 46
AddressFamilyNotSupported 10047 97 47
AddressAlreadyInUse 10048 98 48
AddressNotAvailable 10049 99 49
NetworkDown 10050 100 50
NetworkUnreachable 10051 101 51
NetworkReset 10052 102 52
ConnectionAborted 10053 103 53
ConnectionReset 10054 104 54
NoBufferSpaceAvailable 10055 105 55
IsConnected 10056 106 56
NotConnected 10057 107 57
Shutdown 10058 32 32
TimedOut 10060 110 60
ConnectionRefused 10061 111 61
HostDown 10064 112 64
HostUnreachable 10065 113 65
ProcessLimit 10067 10067 10067
SystemNotReady 10091 10091 10091
VersionNotSupported 10092 10092 10092
NotInitialized 10093 10093 10093
Disconnecting 10101 108 58
TypeNotFound 10109 10109 10109
HostNotFound 11001 -131073 -131073
TryAgain 11002 11 35
NoRecovery 11003 11003 11003
NoData 11004 61 96
SocketError -1 -1 -1

This table may be useful if you work with native socket error codes.

Summary

From this investigation, we’ve learned the following:

  • SocketException.SocketErrorCode returns a value from the SocketError enum. The numerical values of the enum elements always correspond to the Windows socket error codes.
  • SocketException.ErrorCode always returns SocketException.NativeErrorCode.
  • SocketException.NativeErrorCode on .NET Framework and Mono always corresponds to the Windows error codes (even if you are using Mono on Unix). On .NET Core, SocketException.NativeErrorCode equals the corresponding native error code from the current operating system.

SocketErrors-Blog
A few practical recommendations:

  • If you want to write portable code, always use SocketException.SocketErrorCode and compare it with the values of SocketError. Never use raw numerical error codes.
  • If you want to get the native error code on .NET Core (e.g., for passing to another native program), use SocketException.NativeErrorCode. Remember that different Unix-based operating systems (e.g., Linux, macOS, Solaris) have different native code sets. You can get the exact values of the native error codes by using the errno command.

References

  • Microsoft Docs: Windows Sockets Error Codes
  • IBM Knowledge Center: TCP/IP error codes
  • MariaDB: Operating System Error Codes
  • gnu.org: Error Codes
  • Stackoverflow: Identical Error Codes

Subscribe to Blog updates

Discover more

Have you ever got stuck with Socket Error 10060 on windows?

Error 10060 occurs while connecting to the Internet and the client using the proxy system.

At Bobcares, we often receive requests to fix socket errors as part of our Server Management Services.

Today, let’s discuss this error in detail and see how our Support Engineers fix it for our customers.

What causes Socket Error 10060 on windows?

The problem occurs while using proxy servers and when the time to load the web page is not enough.

In such situations, the connection times out and the error occurs.

Recently one of our customers contacted us with this error when he uses proxy service to connect to the internet. It returns the error message as follows.

How to identify Socket Error 10060 on windows?

The first thing is that the error message popping up on the screen when trying to connect to the internet via a proxy server.

Another potential problem could be an inability by the browser to display the web pages.

1. The webpage can’t be shown.
2. There is an issue with the page that attempting to reach and it can’t be shown.

How we fix Socket Error 10060 on windows?

So far, we discuss the socket error in detail. Now let’s see how our Support Engineers fix this error for our customers.

1.  Increase the time-out limit for the loading websites.

In this method, we make modifications to Windows Registry.

In order to avoid possible damage, you should backup Registry. Backups are crucial if something goes wrong.

To do this,

1. First, we open the Registry Editor.

2. Then we go to the Run from >> the Start >> type regedit >> then click OK.

3. After this, we go to the registry subkey.

HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesW3ProxyParameters

4. Then click on>> RequestTimeoutSecs, and then on Modify button.

5. we go to Decimal where you can increase the time limit for loading the Internet sites.

(180 would be more or less an ideal time period)

6. Once we do that, we click on the >> OK button.

7. After all the modifications, we restart the system.

After making modifications in the registry, we also make sure that everything is stable on the system.

2. Verify web proxy connection

Next, we verify the web proxy connections.

To do this,

1. We open the  Run app from the Start and type inetcpl.cpl then click >> OK.

2. When Internet Properties window appears, >> we go to the Connections tab. There go to the Lan settings.

3. Then the Local Area Network (LAN) Settings window shows up.

4. After this, we find the Use a proxy for your Lan box and deselect this option, then click>> OK.

This fixes the socket error.

3. Disable Firewall

Firewall security may sometimes be the reason for socket error 10060 too. So we ask the customers to check the firewall configuration or disable the firewall for a temporary time period

4. Scan for Malware

Another reason for this error is malware infection on the system. so we run an antivirus on the customer’s system or advise them to install antivirus software on the system and run it properly.

It detects and removes all types of malware including Trojans, viruses, adware, spyware and more in seconds.

[Need more assistance to fix Socket Error 10060 on windows? We’ll help you.]

Conclusion

In short, the error occurs while connecting to the Internet and the client using the proxy system. Socket error 10060 on windows indicate the connection problem. Today we discussed how our Support Engineers fix this error for our customers.

PREVENT YOUR SERVER FROM CRASHING!

Never again lose customers to poor server speed! Let us help you.

Our server experts will monitor & maintain your server 24/7 so that it remains lightning fast and secure.

GET STARTED

var google_conversion_label = «owonCMyG5nEQ0aD71QM»;

Socket error is kind of a common error we often face while using the internet for connecting to another computer, sending mails or just browsing. There are several errors having identical codes.

Sometimes the problem occurs because of our firewall and antivirus settings; sometimes the server or the computer we are trying to connect to reports an error. Basically there are lots of errors like this. Here we are giving some errors and their solutions.

Socket Error 10053

This error message reports “Software caused connection abort”.

Cause

There are several things that cause this error to happen.

  1. The established connection may be aborted by software. This can be possibly done by an antivirus program.
  2. Not only the software, it can also happen by network problem or server problem.
  3. If the port is inactive for a long time, the problem may arise.
  4. The MTU (Maximum Transmission Unit) settings can also create the problem.

Solutions

As the problems are widespread, the solutions are also quite dependent on the type of problem.

  1. If the problem is caused by the VPOP3 client while downloading or sending mail, then the antivirus program can cause the problem. Generally McAfee VirusScan 8 and Norton Antivirus 2004 is the reason behind the error. Also other antivirus programs can create the problem.
  2. If a VPOP3 client has stopped working due to some other reason,we have to wait till it gets fixed.
  3. In the case of MTU settings problems, the large value of MTU can be a cause to discard the message in the network. So we have to set the MTU value at 1432 and the MSS (Maximum Segment Size) must be set to 0 or to auto adjust.

Socket Error 10061

socket error 10061connection refused image

This error report says “Connection refused”.

Cause

There are quite a few reasons for this problem.

  1. The target computer may have refused the connection. This happens when the computer is not connected to any running server application.
  2. Sometimes the destination mail server is refusing to receive mail. The spam filter is preventing the mail from being received. This means the SMTP server is sending junk mails.
  3. The firewall can also block the new connection attempt. The Port 25 (needed for SMTP) and the Port 110 (needed for POP) are blocked by the firewall.
  4. The ISP can also be too busy to accept any new connection.

Solutions

There are couple of solutions for this error.

  1. If the error is reported during sending an email then the SMTP has an error. Maybe we have sent too much mail during a short period to the destination mail. So the destination mail server reported the sending mail server as spam. In this context, we can reduce the frequency of sending mail to the mail server. Also we can send the mail via relay server. But the use of the relay server is not quite secure to use as it’s used by spammers.
  2. We can disable the firewall for some period and try to send mail to the destination mail server. If it succeeds then we can be sure that the firewall is creating the problem. So we can add exceptions for the connection in the firewall.

Socket Error 10049

This error report says “Cannot assign requested address”.

Cause

The main reason behind this error is that the address entered is invalid in the IP address. It happens to bind the address which is not valid in the local computer address. Timing issues in the DNS lookup can also create this error.

Solutions

The solutions for this problem are quite limited.

  1. Sometimes the reason behind this problem is the firewall. So if we put the host for our server in the firewall (it can be our system firewall or the antivirus firewall), it can solve the problem.
  2. Also if we forward the port in the internal IP of the new PC which we are trying to connect, it can resolve the problem.
  3. For the timing issue in the DNS lookup we have to follow some tiny steps. In the ‘Diagnostics’ tab in the VPOP3 we have to press ‘TCP/IP Tuning Option’ button and tick the ‘Use synchronous DNS’.

Socket Error 10051

The error report says “Network is unreachable”.

Cause

There are several reasons behind the problem.

  1. The internet connection may be down so the router can find a way to send the data to the destination.
  2. The router may be misconfigured so the router is not able to communicate with the target server.
  3. The firewall may be blocking port 25, which is used for the SMTP client connection to send mails.
  4. If we have two or more routers connected then windows may be misconfigured to communicate.

Solutions

The solutions for this problem are quite simple.

  1. The ISP sometimes blocks port 25 to control the spam through their servers. So we can call them to unblock port 25 and also we can use their own SMTP server.
  2. If the firewall is blocking port 25 then we can add an exception for the port in the settings of firewall.

Socket Error 11004

socket errors

The error report says “Valid name, no data of requested type”. The requested name is valid and was found in the database, but it does not have the correct associated data being resolved for.

Solutions

  1. As the error is associated with DNS so first of all check whether the address typed is correct or not.
  2. Try to connect with the IP address instead of Domain name. Ping the domain name in the command prompt to get the IP address of the domain name.
  3. We also have to be sure that the firewall or any antivirus program isn’t blocking the ports.
  4. A registry scan may help in this context. Any reliable registry scanner software can do the job.

Socket Error 10013

The error message says “Permission denied”.

Cause

An attempt was made to access a socket in a way forbidden by its access permissions. An example is using a broadcast address for sendto without broadcast permission being set using setsockopt (SO_BROADCAST).

Another possible reason for the WSAEACCES error is that when the bind function is called, another application, service, or kernel mode driver is bound to the same address with exclusive access. Such exclusive access is a new feature of Windows NT 4.0 with SP4 and later, and is implemented by using the SO_EXCLUSIVEADDRUSE option.

Solutions

  1. Check the firewall settings whether it is blocking the port 25 or not. If yes then disable the firewall for some time and check whether the same error persists or not. Then we have to change the firewall settings so that it doesn’t block port 25.
  2. A registry scan may help in this context. Any reliable registry scanner software can do the job.

Socket Error 10060

The error report says “Connection timed out”. It means that the connected host failed to respond or the connection failed after some period of time.

Solutions

  1. The error simply means that the SMTP server needs authentication. So if we are using Outlook Express then we should check the box ‘My server requires authentication’.
  2. The firewall may also be blocking the connection. Disabling the firewall may resolve the error.
  3. The SMTP server may also be blocked. So contacting ISP may resolve the problem.

Понравилась статья? Поделить с друзьями:
  • Windows get error message
  • Windows ftp error 530
  • Windows found drivers for your device but encountered an error while attempting to install them
  • Windows found driver software for your device but encountered an error
  • Windows fix disk error