A
download WinSock2Wrapper.cs
Language: C#
LOC: 93
Project Info
ncindy - NCindy is a .NET port of the Cind...work.(ncindy)
Server: Google
Type: svn
...indy\trunk\src\NCindy\Util\
   AbstractDisposable.cs
   AysncCallWrapper.cs
   Configuration.cs
   ElapsedTime.cs
   LangHelper.cs
   LockHelper.cs
   SocketFactory.cs
   ValueTypeWrapper.cs
   WinSock2Wrapper.cs

using System;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Net;

namespace NCindy.Util
{
    public static class WinSock2Wrapper
    {
        #region constants
        public const int SO_CONNECT_TIME = 0x700C;
        public const int INT32_LENGTH = 4;

        private static readonly byte [] KeepAliveOn
            = BitConverter.GetBytes((uint)1);

        private static readonly byte [] KeepAliveOff
            = BitConverter.GetBytes((uint)0);

        private static readonly int UintSize = Marshal.SizeOf(typeof(uint));
        #endregion

        #region pinvoke methods
        [DllImport("ws2_32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern int getsockopt(
            IntPtr socketHandle,
            int level,
            int optname,
            out int optval,
            ref int optlen);

        [DllImport("ws2_32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern int WSAGetLastError();
        #endregion

        /// <summary>
        /// Get the local IPEndpoint which would be used to route to the given remote IPEndpoint.
        /// </summary>
        /// <param name="sock"></param>
        /// <param name="remoteEP"></param>
        /// <returns></returns>
        public static IPEndPoint QueryRoutingInterface(Socket sock,
                                            IPEndPoint remoteEP)
        {
            LangHelper.CheckNullArgument("sock", sock);
            LangHelper.CheckNullArgument("remoteEP", remoteEP);

            SocketAddress sa = remoteEP.Serialize();

            byte[] remoteAddrBytes = new byte[sa.Size];

            for (int i = 0; i < sa.Size; i++)
            {
                remoteAddrBytes[i] = sa[i];
            }

            byte[] localAddrBytes = new byte[remoteAddrBytes.Length];

            sock.IOControl(IOControlCode.RoutingInterfaceQuery,
                           remoteAddrBytes,
                           localAddrBytes);

            for (int i = 0; i < sa.Size; i++)
            {
                sa[i] = localAddrBytes[i];
            }

            EndPoint ep = remoteEP.Create(sa);

            return (IPEndPoint) ep;
        }


        /// <summary>
        /// Get socket connection e
        /// </summary>
        /// <param name="sock"></param>
        /// <returns></returns>
        public static int GetConnectTime(Socket sock)
        {
            if (sock == null)
            {
                throw new ArgumentNullException();
            }

            int connTime;
            int optlen = INT32_LENGTH;

            int retVal = getsockopt(sock.Handle,
                (int)SocketOptionLevel.Socket,
                SO_CONNECT_TIME,
                out connTime,
                ref optlen);

            if (retVal == 0) // getsockopt succeed.
            {
                return connTime;
            }
         
            int errorCode = WSAGetLastError();
            throw new SocketException(errorCode);
        }


        public static void SetKeepAlive(Socket s, bool on, uint time, uint interval)
        {
            /* the native structure
            struct tcp_keepalive {
                ULONG onoff;
                ULONG keepalivetime;
                ULONG keepaliveinterval;
            };
            */

            // marshal the equivalent of the native structure into a byte array
            byte[] inOptionValues = new byte[UintSize * 3];

            System.Buffer.BlockCopy(
                on ? KeepAliveOn : KeepAliveOff,
                0,
                inOptionValues,
                0,
                UintSize);

            System.Buffer.BlockCopy(BitConverter.GetBytes(time),
                                    0,
                                    inOptionValues,
                                    UintSize,
                                    UintSize);

            System.Buffer.BlockCopy(BitConverter.GetBytes(interval),
                                    0,
                                    inOptionValues,
                                    UintSize * 2,
                                    UintSize);

            // call WSAIoctl via IOControl
            s.IOControl(IOControlCode.KeepAliveValues, inOptionValues, null);
        }
    }
}

About Koders | Resources | Downloads | Support | Black Duck | Terms of Service | DMCA | Privacy Policy | Contact Us