/// <summary>
        /// Intercept the ip traffic in a designated address. All the traffic will be sent to sdkListeningIpAddress.
        /// </summary>
        /// <param name="transportType">TCP or UDP . </param>
        /// <param name="isBlocking">Whether this request is a blocking request.</param>
        /// <param name="interceptedEndPoint">The intercepted IP/Port of the windows service . </param>
        /// <param name="sdkLocalListeningEndPoint">The IP/Port listened by SDK . </param>
        /// <returns>LspSession, which is corresponding to each intercepted endpoint. Return null if failed.</returns>
        internal void InterceptTraffic(StackTransportType transportType, bool isBlocking, IPEndPoint interceptedEndPoint,
                                       IPEndPoint sdkLocalListeningEndPoint)
        {
            if (disposed)
            {
                return;
            }

            if (!isConnected)
            {
                Connect();
            }

            if (sdkLocalListeningEndPoint == null)
            {
                throw new ArgumentNullException("sdkLocalListeningEndPoint");
            }

            if (sdkLocalListeningEndPoint.AddressFamily == AddressFamily.InterNetwork &&
                sdkLocalListeningEndPoint.Address == IPAddress.Any)
            {
                sdkLocalListeningEndPoint.Address = IPAddress.Loopback;
            }
            else if (sdkLocalListeningEndPoint.AddressFamily == AddressFamily.InterNetworkV6 &&
                     sdkLocalListeningEndPoint.Address == IPAddress.IPv6Any)
            {
                sdkLocalListeningEndPoint.Address = IPAddress.IPv6Loopback;
            }

            LspInterceptionRequest request = new LspInterceptionRequest(transportType, isBlocking,
                                                                        interceptedEndPoint, sdkLocalListeningEndPoint);

            InternalSend(request.Encode());


            byte[] recvBuf;
            int    recvLen = LspMessage.ReceiveWholeMessage(this.socket, Marshal.SizeOf(typeof(LspInterceptionResponseMsg)), out recvBuf);

            if (recvLen != Marshal.SizeOf(typeof(LspInterceptionResponseMsg)))
            {
                if (isBlocking)
                {
                    throw new InvalidOperationException("BlockTraffic failed");
                }
                else
                {
                    throw new InvalidOperationException("InterceptTraffic failed");
                }
            }

            LspInterceptionResponse response = LspInterceptionResponse.Decode(recvBuf) as LspInterceptionResponse;

            if (response != null && response.Status == 0) //success
            {
                LspSessionInfoCollection sessionInfoCollection = new LspSessionInfoCollection();
                sessionInfoCollection.lspSession = response.Session;
                sessionInfoCollection.lspSession.InterceptedEndPoint = response.InterceptedEndPoint;
                sessionInfoCollection.endPoints = new Dictionary <string, IPEndPoint>();
                this[sdkLocalListeningEndPoint, transportType] = sessionInfoCollection;
            }
            else
            {
                if (isBlocking)
                {
                    throw new InvalidOperationException("BlockTraffic failed");
                }
                else
                {
                    throw new InvalidOperationException("InterceptTraffic failed");
                }
            }
        }
        /// <summary>
        /// Intercept the ip traffic in a designated address. All the traffic will be sent to sdkListeningIpAddress. 
        /// </summary>
        /// <param name="transportType">TCP or UDP . </param>
        /// <param name="isBlocking">Whether this request is a blocking request.</param>
        /// <param name="interceptedEndPoint">The intercepted IP/Port of the windows service . </param>
        /// <param name="sdkLocalListeningEndPoint">The IP/Port listened by SDK . </param>
        /// <returns>LspSession, which is corresponding to each intercepted endpoint. Return null if failed.</returns>
        internal void InterceptTraffic(StackTransportType transportType, bool isBlocking, IPEndPoint interceptedEndPoint,
            IPEndPoint sdkLocalListeningEndPoint)
        {
            if (disposed)
            {
                return;
            }

            if (!isConnected)
            {
                Connect();
            }

            if (sdkLocalListeningEndPoint == null)
            {
                throw new ArgumentNullException("sdkLocalListeningEndPoint");
            }

            if (sdkLocalListeningEndPoint.AddressFamily == AddressFamily.InterNetwork &&
                sdkLocalListeningEndPoint.Address == IPAddress.Any)
            {
                sdkLocalListeningEndPoint.Address = IPAddress.Loopback;
            }
            else if (sdkLocalListeningEndPoint.AddressFamily == AddressFamily.InterNetworkV6 &&
                sdkLocalListeningEndPoint.Address == IPAddress.IPv6Any)
            {
                sdkLocalListeningEndPoint.Address = IPAddress.IPv6Loopback;
            }

            LspInterceptionRequest request = new LspInterceptionRequest(transportType, isBlocking,
                interceptedEndPoint, sdkLocalListeningEndPoint);
            InternalSend(request.Encode());

            byte[] recvBuf;
            int recvLen = LspMessage.ReceiveWholeMessage(this.socket, Marshal.SizeOf(typeof(LspInterceptionResponseMsg)), out recvBuf);
            if (recvLen != Marshal.SizeOf(typeof(LspInterceptionResponseMsg)))
            {
                if (isBlocking)
                {
                    throw new InvalidOperationException("BlockTraffic failed");
                }
                else
                {
                    throw new InvalidOperationException("InterceptTraffic failed");
                }
            }

            LspInterceptionResponse response = LspInterceptionResponse.Decode(recvBuf) as LspInterceptionResponse;

            if (response != null && response.Status == 0) //success
            {
                LspSessionInfoCollection sessionInfoCollection = new LspSessionInfoCollection();
                sessionInfoCollection.lspSession = response.Session;
                sessionInfoCollection.lspSession.InterceptedEndPoint = response.InterceptedEndPoint;
                sessionInfoCollection.endPoints = new Dictionary<string, IPEndPoint>();
                this[sdkLocalListeningEndPoint, transportType] = sessionInfoCollection;
            }
            else
            {
                if (isBlocking)
                {
                    throw new InvalidOperationException("BlockTraffic failed");
                }
                else
                {
                    throw new InvalidOperationException("InterceptTraffic failed");
                }
            }
        }