SOCKADDR (Structures)
Last changed: -194.176.224.41

.
Summary
TODO - a short description

C# Definition:

// WinsockSockAddr takes an IPAddress of IPEndpoint on creation, then provides a
// pinned PSOCKADDR to be used for async PInvoke calls.  The owner and pending
// async calls may reference the same instance at the same time, and have
// different independent needs with regards to the lifetime of the pinned
// PSOCKADDR.  So WinsockSockAddr guarantees the pinned copy is available so
// long as the WinsockSockAddr instance owning that pinned copy is referenced.

// NOTENOTE:  System.Net.Endpoint.Serialize will provide a System.Net.SocketAddress
// which mostly fulfills the same use as the class below.  It does not pin the
// result though.  Consider passing the result of System.Net.Endpoint.Serialize()
// as X to GCHandle.Alloc(X, GCHandleType.Pinned) instead of picking up the
// entire class below.

[StructLayout(LayoutKind.Sequential)]

    public struct sockaddr_in
    {
        public ADDRESS_FAMILIES sin_family;
        public ushort sin_port;
        public in_addr sin_addr;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
        public byte[] sin_zero;
    }

[StructLayout(LayoutKind.Explicit, Size = 4)]

    public struct in_addr
    {
        [FieldOffset(0)]
        public byte s_b1;
        [FieldOffset(1)]
        public byte s_b2;
        [FieldOffset(2)]
        public byte s_b3;
        [FieldOffset(3)]
        public byte s_b4;

        [FieldOffset(0)]
        public ushort s_w1;
        [FieldOffset(2)]
        public ushort s_w2;

        [FieldOffset(0)]
        public uint S_addr;

        /// <summary>
        /// can be used for most tcp & ip code
        /// </summary>
        public uint s_addr { get { return S_addr; } }

        /// <summary>
        /// host on imp
        /// </summary>
        public byte s_host { get { return s_b2; } }

        /// <summary>
        /// network
        /// </summary>
        public byte s_net { get { return s_b1; } }

        /// <summary>
        /// imp
        /// </summary>
        public ushort s_imp { get { return s_w2; } }

        /// <summary>
        /// imp #
        /// </summary>
        public byte s_impno { get { return s_b4; } }

        /// <summary>
        /// logical host
        /// </summary>
        public byte s_lh { get { return s_b3; } }
    }

class WinsockSockAddr
{
     const Int16 AF_INET = 2;
     const Int16 AF_INET6 = 23;

     [StructLayout(LayoutKind.Sequential)]
     struct SOCKADDR_IN
     {
     public Int16 _family;
     public Int16 _port;
     public Byte _addr0;
     public Byte _addr1;
     public Byte _addr2;
     public Byte _addr3;
     public Int32 _nothing;
     }

     static readonly int SIZEOF_SOCKADDR_IN = Marshal.SizeOf(typeof(SOCKADDR_IN));

     [StructLayout(LayoutKind.Sequential)]
     struct SOCKADDR_IN6
     {
     public Int16 _family;
     public Int16 _port;
     public Int32 _flowInfo;
     public Byte _addr0;
     public Byte _addr1;
     public Byte _addr2;
     public Byte _addr3;
     public Byte _addr4;
     public Byte _addr5;
     public Byte _addr6;
     public Byte _addr7;
     public Byte _addr8;
     public Byte _addr9;
     public Byte _addr10;
     public Byte _addr11;
     public Byte _addr12;
     public Byte _addr13;
     public Byte _addr14;
     public Byte _addr15;
     public Int32 _scopeID;
     }

     static readonly int SIZEOF_SOCKADDR_IN6 = Marshal.SizeOf(typeof(SOCKADDR_IN6));

     // Depending on the family type of address represented, either a SOCKADDR_IN
     // or a SOCKADDR_IN6 will be referenced by _addr.  We'll pin the same object
     // to _pinAddr, and finally keep a IntPtr to the alloc.
     object _addr;
     GCHandle _pinAddr;
     IntPtr _pAddr;

     public WinsockSockAddr(IPEndPoint source)
     : this(source.Address, (short)source.Port)
     {
     }

     public WinsockSockAddr(IPAddress source)
     : this(source, 0)
     {
     }

     public WinsockSockAddr(IPAddress source, short port)
     {
     _pAddr = (IntPtr)0;

     if (source.AddressFamily == AddressFamily.InterNetwork)
     {
         SOCKADDR_IN a;
         Byte[] addr = source.GetAddressBytes();
         Debug.Assert(addr.Length == 4);

         a._family = AF_INET;
         a._port = IPAddress.HostToNetworkOrder(port);
         a._addr0 = addr[0];
         a._addr1 = addr[1];
         a._addr2 = addr[2];
         a._addr3 = addr[3];
         a._nothing = 0;

         _addr = a;
     }
     else if (source.AddressFamily == AddressFamily.InterNetworkV6)
     {
         SOCKADDR_IN6 a;
         Byte[] addr = source.GetAddressBytes();
         Debug.Assert(addr.Length == 16);

         a._family = AF_INET6;
         a._port = IPAddress.HostToNetworkOrder(port);
         a._flowInfo = 0;
         a._addr0 = addr[0];
         a._addr1 = addr[1];
         a._addr2 = addr[2];
         a._addr3 = addr[3];
         a._addr4 = addr[4];
         a._addr5 = addr[5];
         a._addr6 = addr[6];
         a._addr7 = addr[7];
         a._addr8 = addr[8];
         a._addr9 = addr[9];
         a._addr10 = addr[10];
         a._addr11 = addr[11];
         a._addr12 = addr[12];
         a._addr13 = addr[13];
         a._addr14 = addr[14];
         a._addr15 = addr[15];
         a._scopeID = (Int32)source.ScopeId;

         _addr = a;
     }
     else
     {
         throw new ArgumentException();
     }

     _pinAddr = GCHandle.Alloc(_addr, GCHandleType.Pinned);
     _pAddr = _pinAddr.AddrOfPinnedObject();
     }


     void Close()
     {
     if (_pinAddr.IsAllocated)
     {
         _pinAddr.Free();
     }

     _addr = null;
     _pAddr = (IntPtr)0;
     }

     ~WinsockSockAddr()
     {
     Close();
     }

     public IntPtr PinnedSockAddr
     { get { return _pAddr; } }
}

Notes:

None.

This sample code also shows how to work with this structure in C#: http://dotnetcodebox.blogspot.com/2012/01/how-to-use-umanaged-sockaddr-structure.html .

Documentation
SOCKADDR on MSDN