TCPClient.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / whidbey / netfxsp / ndp / fx / src / Net / System / Net / Sockets / TCPClient.cs / 1 / TCPClient.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

 
namespace System.Net.Sockets { 

    using System.Threading; 
    using System.Security.Permissions;

    /// 
    /// The  class provide TCP services at a higher level 
    ///    of abstraction than the  class. 
    ///    is used to create a Client connection to a remote host. 
    ///  
    public class TcpClient : IDisposable {
 
        Socket m_ClientSocket;
        bool m_Active;
        NetworkStream m_DataStream;
 
        //
        // IPv6: Maintain address family for the client 
        // 
        AddressFamily m_Family = AddressFamily.InterNetwork;
 
        // specify local IP and port
        /// 
        ///    
        ///       Initializes a new instance of the  
        ///       class with the specified end point.
        ///     
        ///  
        public TcpClient(IPEndPoint localEP) {
            if(Logging.On)Logging.Enter(Logging.Sockets, this, "TcpClient", localEP); 
            if (localEP==null) {
                throw new ArgumentNullException("localEP");
            }
            // 
            // IPv6: Establish address family before creating a socket
            // 
            m_Family = localEP.AddressFamily; 

            initialize(); 
            Client.Bind(localEP);
            if(Logging.On)Logging.Exit(Logging.Sockets, this, "TcpClient", "");
        }
 
        // TcpClient(IPaddress localaddr); // port is arbitrary
        // TcpClient(int outgoingPort); // local IP is arbitrary 
 
        // address+port is arbitrary
        ///  
        ///    
        ///       Initializes a new instance of the  class.
        ///    
        ///  
        public TcpClient() : this(AddressFamily.InterNetwork) {
            if(Logging.On)Logging.Enter(Logging.Sockets, this, "TcpClient", null); 
            if(Logging.On)Logging.Exit(Logging.Sockets, this, "TcpClient", null); 
        }
 
        /// 
        ///    
        ///       Initializes a new instance of the  class.
        ///     
        /// 
#if COMNET_DISABLEIPV6 
        private TcpClient(AddressFamily family) { 
#else
        public TcpClient(AddressFamily family) { 
#endif
            if(Logging.On)Logging.Enter(Logging.Sockets, this, "TcpClient", family);
            //
            // Validate parameter 
            //
            if ( family != AddressFamily.InterNetwork && family != AddressFamily.InterNetworkV6) { 
                throw new ArgumentException(SR.GetString(SR.net_protocol_invalid_family, "TCP"), "family"); 
            }
 
            m_Family = family;

            initialize();
            if(Logging.On)Logging.Exit(Logging.Sockets, this, "TcpClient", null); 
        }
 
        // bind and connect 
        /// 
        /// Initializes a new instance of the  class and connects to the 
        ///    specified port on the specified host.
        /// 
        public TcpClient(string hostname, int port) {
            if(Logging.On)Logging.Enter(Logging.Sockets, this, "TcpClient", hostname); 
            if (hostname==null) {
                throw new ArgumentNullException("hostname"); 
            } 
            if (!ValidationHelper.ValidateTcpPort(port)) {
                throw new ArgumentOutOfRangeException("port"); 
            }
            //
            // IPv6: Delay creating the client socket until we have
            //       performed DNS resolution and know which address 
            //       families we can use.
            // 
            //initialize(); 

            try{ 
                Connect(hostname, port);
            }

            catch(Exception e){ 
                if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
                    throw; 
                } 

                if(m_ClientSocket != null){ 
                    m_ClientSocket.Close();
                }
                throw e;
            } 

            if(Logging.On)Logging.Exit(Logging.Sockets, this, "TcpClient", null); 
        } 

        // 
        // used by TcpListener.Accept()
        //
        internal TcpClient(Socket acceptedSocket) {
            if(Logging.On)Logging.Enter(Logging.Sockets, this, "TcpClient", acceptedSocket); 
            Client = acceptedSocket;
            m_Active = true; 
            if(Logging.On)Logging.Exit(Logging.Sockets, this, "TcpClient", null); 
        }
 
        /// 
        ///    
        ///       Used by the class to provide
        ///       the underlying network socket. 
        ///    
        ///  
        public Socket Client { 
            get {
                return m_ClientSocket; 
            }
            set {
                m_ClientSocket = value;
            } 
        }
 
        ///  
        ///    
        ///       Used by the class to indicate that a connection has been made. 
        ///    
        /// 
        protected bool Active {
            get { 
                return m_Active;
            } 
            set { 
                m_Active = value;
            } 
        }

        public int Available {get {return m_ClientSocket.Available;}}
        public bool Connected  {get {return m_ClientSocket.Connected;}} 
        public bool ExclusiveAddressUse {
            get { 
                return m_ClientSocket.ExclusiveAddressUse; 
            }
            set{ 
                m_ClientSocket.ExclusiveAddressUse = value;
            }
        }    //new
 

 
        ///  
        ///    
        ///       Connects the Client to the specified port on the specified host. 
        ///    
        /// 
        public void Connect(string hostname, int port) {
            if(Logging.On)Logging.Enter(Logging.Sockets, this, "Connect", hostname); 
            if (m_CleanedUp){
                throw new ObjectDisposedException(this.GetType().FullName); 
            } 
            if (hostname==null) {
                throw new ArgumentNullException("hostname"); 
            }
            if (!ValidationHelper.ValidateTcpPort(port)) {
                throw new ArgumentOutOfRangeException("port");
            } 
            //
            // Check for already connected and throw here. This check 
            // is not required in the other connect methods as they 
            // will throw from WinSock. Here, the situation is more
            // complex since we have to resolve a hostname so it's 
            // easier to simply block the request up front.
            //
            if ( m_Active ) {
                throw new SocketException(SocketError.IsConnected); 
            }
 
            // 
            // IPv6: We need to process each of the addresses return from
            //       DNS when trying to connect. Use of AddressList[0] is 
            //       bad form.
            //

 
            IPAddress[] addresses = Dns.GetHostAddresses(hostname);
            Exception   lastex = null; 
            Socket ipv6Socket = null; 
            Socket ipv4Socket = null;
 
            try{
                if (m_ClientSocket == null) {
                    if (Socket.SupportsIPv4){
                        ipv4Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
                    }
                    if (Socket.OSSupportsIPv6){ 
                        ipv6Socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp); 
                    }
                } 

                foreach (IPAddress address in addresses)
                {
                    try { 
                        if ( m_ClientSocket == null ) {
                            // 
                            // We came via the  constructor. Set the 
                            // address family appropriately, create the socket and
                            // try to connect. 
                            //
                            if (address.AddressFamily == AddressFamily.InterNetwork && ipv4Socket != null) {
                                ipv4Socket.Connect(address,port);
                                m_ClientSocket = ipv4Socket; 
                                if (ipv6Socket != null)
                                    ipv6Socket.Close(); 
                            } 
                            else if (ipv6Socket != null)
                            { 
                                ipv6Socket.Connect(address, port);
                                m_ClientSocket = ipv6Socket;
                                if (ipv4Socket != null)
                                    ipv4Socket.Close(); 
                            }
 
                            m_Family = address.AddressFamily; 
                            m_Active = true;
                            break; 
                        }
                        else if ( address.AddressFamily == m_Family ) {
                            //
                            // Only use addresses with a matching family 
                            //
                            Connect( new IPEndPoint(address,port) ); 
                            m_Active = true; 
                            break;
                        } 
                    }

                    catch ( Exception ex )
                    { 
                        if (ex is ThreadAbortException || ex is StackOverflowException || ex is OutOfMemoryException) {
                            throw; 
                        } 
                        lastex = ex;
                    } 
                }
            }

            catch(Exception ex){ 
                if (ex is ThreadAbortException || ex is StackOverflowException || ex is OutOfMemoryException) {
                    throw; 
                } 
                lastex = ex;
            } 

            finally{

                //cleanup temp sockets if failed 
                //main socket gets closed when tcpclient gets closed
 
                //did we connect? 
                if ( !m_Active ) {
                    if (ipv6Socket != null) { 
                        ipv6Socket.Close();
                    }

                    if (ipv4Socket != null) { 
                        ipv4Socket.Close();
                    } 
 

                    // 
                    // The connect failed - rethrow the last error we had
                    //
                    if ( lastex != null )
                        throw lastex; 
                    else
                        throw new SocketException(SocketError.NotConnected); 
                } 
            }
 
            if(Logging.On)Logging.Exit(Logging.Sockets, this, "Connect", null);
        }

        ///  
        ///    
        ///       Connects the Client to the specified port on the specified host. 
        ///     
        /// 
        public void Connect(IPAddress address, int port) { 
            if(Logging.On)Logging.Enter(Logging.Sockets, this, "Connect", address);
            if (m_CleanedUp){
                throw new ObjectDisposedException(this.GetType().FullName);
            } 
            if (address==null) {
                throw new ArgumentNullException("address"); 
            } 
            if (!ValidationHelper.ValidateTcpPort(port)) {
                throw new ArgumentOutOfRangeException("port"); 
            }
            IPEndPoint remoteEP = new IPEndPoint(address, port);
            Connect(remoteEP);
            if(Logging.On)Logging.Exit(Logging.Sockets, this, "Connect", null); 
        }
 
        ///  
        ///    
        ///       Connect the Client to the specified end point. 
        ///    
        /// 
        public void Connect(IPEndPoint remoteEP) {
            if(Logging.On)Logging.Enter(Logging.Sockets, this, "Connect", remoteEP); 
            if (m_CleanedUp){
                throw new ObjectDisposedException(this.GetType().FullName); 
            } 
            if (remoteEP==null) {
                throw new ArgumentNullException("remoteEP"); 
            }
            Client.Connect(remoteEP);
            m_Active = true;
            if(Logging.On)Logging.Exit(Logging.Sockets, this, "Connect", null); 
        }
 
 

        //methods 
        public void Connect(IPAddress[] ipAddresses, int port){
            if(Logging.On)Logging.Enter(Logging.Sockets, this, "Connect", ipAddresses);
            Client.Connect(ipAddresses, port);
            m_Active = true; 
            if(Logging.On)Logging.Exit(Logging.Sockets, this, "Connect", null);
        } 
 

        [HostProtection(ExternalThreading=true)] 
        public IAsyncResult BeginConnect(string host, int port, AsyncCallback requestCallback, object state)
        {
            if(Logging.On)Logging.Enter(Logging.Sockets, this, "BeginConnect", host);
            IAsyncResult result = Client.BeginConnect(host, port, requestCallback, state); 
            if(Logging.On)Logging.Exit(Logging.Sockets, this, "BeginConnect", null);
            return result; 
        } 

        [HostProtection(ExternalThreading=true)] 
        public IAsyncResult BeginConnect(IPAddress address, int port, AsyncCallback requestCallback, object state)
        {
            if(Logging.On)Logging.Enter(Logging.Sockets, this, "BeginConnect", address);
            IAsyncResult result = Client.BeginConnect(address, port, requestCallback, state); 
            if(Logging.On)Logging.Exit(Logging.Sockets, this, "BeginConnect", null);
            return result; 
        } 

        [HostProtection(ExternalThreading=true)] 
        public IAsyncResult BeginConnect(IPAddress[] addresses, int port, AsyncCallback requestCallback, object state)
        {

            if(Logging.On)Logging.Enter(Logging.Sockets, this, "BeginConnect", addresses); 
            IAsyncResult result = Client.BeginConnect(addresses, port, requestCallback, state);
            if(Logging.On)Logging.Exit(Logging.Sockets, this, "BeginConnect", null); 
            return result; 
        }
 
        public void EndConnect(IAsyncResult asyncResult){

            if(Logging.On)Logging.Enter(Logging.Sockets, this, "EndConnect", asyncResult);
            Client.EndConnect(asyncResult); 
            m_Active = true;
            if(Logging.On)Logging.Exit(Logging.Sockets, this, "EndConnect", null); 
        } 

 



        ///  
        ///    
        ///       Returns the stream used to read and write data to the 
        ///       remote host. 
        ///    
        ///  
        public NetworkStream GetStream() {
            if(Logging.On)Logging.Enter(Logging.Sockets, this, "GetStream", "");
            if (m_CleanedUp){
                throw new ObjectDisposedException(this.GetType().FullName); 
            }
            if (!Client.Connected) { 
                throw new InvalidOperationException(SR.GetString(SR.net_notconnected)); 
            }
            if (m_DataStream==null) { 
                m_DataStream = new NetworkStream(Client, true);
            }
            if(Logging.On)Logging.Exit(Logging.Sockets, this, "GetStream", m_DataStream);
            return m_DataStream; 
        }
 
        ///  
        ///    
        ///       Disposes the Tcp connection. 
        ///    
        /// 
        //UEUE
        public void Close() { 
            if(Logging.On)Logging.Enter(Logging.Sockets, this, "Close", "");
            GlobalLog.Print("TcpClient::Close()"); 
            ((IDisposable)this).Dispose(); 
            if(Logging.On)Logging.Exit(Logging.Sockets, this, "Close", "");
        } 

        private bool m_CleanedUp = false;

        protected virtual void Dispose(bool disposing) { 
            if(Logging.On)Logging.Enter(Logging.Sockets, this, "Dispose", "");
            if (m_CleanedUp) { 
                if(Logging.On)Logging.Exit(Logging.Sockets, this, "Dispose", ""); 
                return;
            } 

            if (disposing) {
                IDisposable dataStream = m_DataStream;
                if (dataStream != null) 
                {
                    dataStream.Dispose(); 
                } 
                else
                { 
                    //
                    // if the NetworkStream wasn't created, the Socket might
                    // still be there and needs to be closed. In the case in which
                    // we are bound to a local IPEndPoint this will remove the 
                    // binding and free up the IPEndPoint for later uses.
                    // 
                    Socket chkClientSocket = Client; 
                    if (chkClientSocket!= null) {
                        try { 
                            chkClientSocket.InternalShutdown(SocketShutdown.Both);
                        }
                        finally {
                            chkClientSocket.Close(); 
                            Client = null;
                        } 
                    } 
                }
 
                GC.SuppressFinalize(this);
            }

            m_CleanedUp = true; 
            if(Logging.On)Logging.Exit(Logging.Sockets, this, "Dispose", "");
        } 
 
        /// 
        void IDisposable.Dispose() { 
            Dispose(true);
        }

        ~TcpClient() { 
#if DEBUG
            GlobalLog.SetThreadSource(ThreadKinds.Finalization); 
            using (GlobalLog.SetThreadKind(ThreadKinds.System | ThreadKinds.Async)) { 
#endif
            Dispose(false); 
#if DEBUG
            }
#endif
        } 

        ///  
        ///     
        ///       Gets or sets the size of the receive buffer in bytes.
        ///     
        /// 
        public int ReceiveBufferSize {
            get {
                return numericOption(SocketOptionLevel.Socket, 
                                     SocketOptionName.ReceiveBuffer);
            } 
            set { 
                Client.SetSocketOption(SocketOptionLevel.Socket,
                                  SocketOptionName.ReceiveBuffer, value); 
            }
        }

 
        /// 
        ///     
        ///       Gets or 
        ///       sets the size of the send buffer in bytes.
        ///     
        /// 
        public int SendBufferSize {
            get {
                return numericOption(SocketOptionLevel.Socket, 
                                     SocketOptionName.SendBuffer);
            } 
 
            set {
                Client.SetSocketOption(SocketOptionLevel.Socket, 
                                  SocketOptionName.SendBuffer, value);
            }
        }
 
        /// 
        ///     
        ///       Gets or sets the receive time out value of the connection in seconds. 
        ///    
        ///  
        public int ReceiveTimeout {
            get {
                return numericOption(SocketOptionLevel.Socket,
                                     SocketOptionName.ReceiveTimeout); 
            }
            set { 
                Client.SetSocketOption(SocketOptionLevel.Socket, 
                                  SocketOptionName.ReceiveTimeout, value);
            } 
        }

        /// 
        ///     
        ///       Gets or sets the send time out value of the connection in seconds.
        ///     
        ///  
        public int SendTimeout {
            get { 
                return numericOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout);
            }

            set { 
                Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, value);
            } 
        } 

        ///  
        ///    
        ///       Gets or sets the value of the connection's linger option.
        ///    
        ///  
        public LingerOption LingerState {
            get { 
                return (LingerOption)Client.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger); 
            }
            set { 
                Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, value);
            }
        }
 
        /// 
        ///     
        ///       Enables or disables delay when send or receive buffers are full. 
        ///    
        ///  
        public bool NoDelay {
            get {
                return numericOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay) != 0 ? true : false;
            } 
            set {
                Client.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, value ? 1 : 0); 
            } 
        }
 
        private void initialize() {
            //
            // IPv6: Use the address family from the constructor (or Connect method)
            // 
            Client = new Socket(m_Family, SocketType.Stream, ProtocolType.Tcp);
            m_Active = false; 
        } 

        private int numericOption(SocketOptionLevel optionLevel, SocketOptionName optionName) { 
            return (int)Client.GetSocketOption(optionLevel, optionName);
        }

    }; // class TCPClient 

 
} // namespace System.Net.Sockets 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

 
namespace System.Net.Sockets { 

    using System.Threading; 
    using System.Security.Permissions;

    /// 
    /// The  class provide TCP services at a higher level 
    ///    of abstraction than the  class. 
    ///    is used to create a Client connection to a remote host. 
    ///  
    public class TcpClient : IDisposable {
 
        Socket m_ClientSocket;
        bool m_Active;
        NetworkStream m_DataStream;
 
        //
        // IPv6: Maintain address family for the client 
        // 
        AddressFamily m_Family = AddressFamily.InterNetwork;
 
        // specify local IP and port
        /// 
        ///    
        ///       Initializes a new instance of the  
        ///       class with the specified end point.
        ///     
        ///  
        public TcpClient(IPEndPoint localEP) {
            if(Logging.On)Logging.Enter(Logging.Sockets, this, "TcpClient", localEP); 
            if (localEP==null) {
                throw new ArgumentNullException("localEP");
            }
            // 
            // IPv6: Establish address family before creating a socket
            // 
            m_Family = localEP.AddressFamily; 

            initialize(); 
            Client.Bind(localEP);
            if(Logging.On)Logging.Exit(Logging.Sockets, this, "TcpClient", "");
        }
 
        // TcpClient(IPaddress localaddr); // port is arbitrary
        // TcpClient(int outgoingPort); // local IP is arbitrary 
 
        // address+port is arbitrary
        ///  
        ///    
        ///       Initializes a new instance of the  class.
        ///    
        ///  
        public TcpClient() : this(AddressFamily.InterNetwork) {
            if(Logging.On)Logging.Enter(Logging.Sockets, this, "TcpClient", null); 
            if(Logging.On)Logging.Exit(Logging.Sockets, this, "TcpClient", null); 
        }
 
        /// 
        ///    
        ///       Initializes a new instance of the  class.
        ///     
        /// 
#if COMNET_DISABLEIPV6 
        private TcpClient(AddressFamily family) { 
#else
        public TcpClient(AddressFamily family) { 
#endif
            if(Logging.On)Logging.Enter(Logging.Sockets, this, "TcpClient", family);
            //
            // Validate parameter 
            //
            if ( family != AddressFamily.InterNetwork && family != AddressFamily.InterNetworkV6) { 
                throw new ArgumentException(SR.GetString(SR.net_protocol_invalid_family, "TCP"), "family"); 
            }
 
            m_Family = family;

            initialize();
            if(Logging.On)Logging.Exit(Logging.Sockets, this, "TcpClient", null); 
        }
 
        // bind and connect 
        /// 
        /// Initializes a new instance of the  class and connects to the 
        ///    specified port on the specified host.
        /// 
        public TcpClient(string hostname, int port) {
            if(Logging.On)Logging.Enter(Logging.Sockets, this, "TcpClient", hostname); 
            if (hostname==null) {
                throw new ArgumentNullException("hostname"); 
            } 
            if (!ValidationHelper.ValidateTcpPort(port)) {
                throw new ArgumentOutOfRangeException("port"); 
            }
            //
            // IPv6: Delay creating the client socket until we have
            //       performed DNS resolution and know which address 
            //       families we can use.
            // 
            //initialize(); 

            try{ 
                Connect(hostname, port);
            }

            catch(Exception e){ 
                if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
                    throw; 
                } 

                if(m_ClientSocket != null){ 
                    m_ClientSocket.Close();
                }
                throw e;
            } 

            if(Logging.On)Logging.Exit(Logging.Sockets, this, "TcpClient", null); 
        } 

        // 
        // used by TcpListener.Accept()
        //
        internal TcpClient(Socket acceptedSocket) {
            if(Logging.On)Logging.Enter(Logging.Sockets, this, "TcpClient", acceptedSocket); 
            Client = acceptedSocket;
            m_Active = true; 
            if(Logging.On)Logging.Exit(Logging.Sockets, this, "TcpClient", null); 
        }
 
        /// 
        ///    
        ///       Used by the class to provide
        ///       the underlying network socket. 
        ///    
        ///  
        public Socket Client { 
            get {
                return m_ClientSocket; 
            }
            set {
                m_ClientSocket = value;
            } 
        }
 
        ///  
        ///    
        ///       Used by the class to indicate that a connection has been made. 
        ///    
        /// 
        protected bool Active {
            get { 
                return m_Active;
            } 
            set { 
                m_Active = value;
            } 
        }

        public int Available {get {return m_ClientSocket.Available;}}
        public bool Connected  {get {return m_ClientSocket.Connected;}} 
        public bool ExclusiveAddressUse {
            get { 
                return m_ClientSocket.ExclusiveAddressUse; 
            }
            set{ 
                m_ClientSocket.ExclusiveAddressUse = value;
            }
        }    //new
 

 
        ///  
        ///    
        ///       Connects the Client to the specified port on the specified host. 
        ///    
        /// 
        public void Connect(string hostname, int port) {
            if(Logging.On)Logging.Enter(Logging.Sockets, this, "Connect", hostname); 
            if (m_CleanedUp){
                throw new ObjectDisposedException(this.GetType().FullName); 
            } 
            if (hostname==null) {
                throw new ArgumentNullException("hostname"); 
            }
            if (!ValidationHelper.ValidateTcpPort(port)) {
                throw new ArgumentOutOfRangeException("port");
            } 
            //
            // Check for already connected and throw here. This check 
            // is not required in the other connect methods as they 
            // will throw from WinSock. Here, the situation is more
            // complex since we have to resolve a hostname so it's 
            // easier to simply block the request up front.
            //
            if ( m_Active ) {
                throw new SocketException(SocketError.IsConnected); 
            }
 
            // 
            // IPv6: We need to process each of the addresses return from
            //       DNS when trying to connect. Use of AddressList[0] is 
            //       bad form.
            //

 
            IPAddress[] addresses = Dns.GetHostAddresses(hostname);
            Exception   lastex = null; 
            Socket ipv6Socket = null; 
            Socket ipv4Socket = null;
 
            try{
                if (m_ClientSocket == null) {
                    if (Socket.SupportsIPv4){
                        ipv4Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
                    }
                    if (Socket.OSSupportsIPv6){ 
                        ipv6Socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp); 
                    }
                } 

                foreach (IPAddress address in addresses)
                {
                    try { 
                        if ( m_ClientSocket == null ) {
                            // 
                            // We came via the  constructor. Set the 
                            // address family appropriately, create the socket and
                            // try to connect. 
                            //
                            if (address.AddressFamily == AddressFamily.InterNetwork && ipv4Socket != null) {
                                ipv4Socket.Connect(address,port);
                                m_ClientSocket = ipv4Socket; 
                                if (ipv6Socket != null)
                                    ipv6Socket.Close(); 
                            } 
                            else if (ipv6Socket != null)
                            { 
                                ipv6Socket.Connect(address, port);
                                m_ClientSocket = ipv6Socket;
                                if (ipv4Socket != null)
                                    ipv4Socket.Close(); 
                            }
 
                            m_Family = address.AddressFamily; 
                            m_Active = true;
                            break; 
                        }
                        else if ( address.AddressFamily == m_Family ) {
                            //
                            // Only use addresses with a matching family 
                            //
                            Connect( new IPEndPoint(address,port) ); 
                            m_Active = true; 
                            break;
                        } 
                    }

                    catch ( Exception ex )
                    { 
                        if (ex is ThreadAbortException || ex is StackOverflowException || ex is OutOfMemoryException) {
                            throw; 
                        } 
                        lastex = ex;
                    } 
                }
            }

            catch(Exception ex){ 
                if (ex is ThreadAbortException || ex is StackOverflowException || ex is OutOfMemoryException) {
                    throw; 
                } 
                lastex = ex;
            } 

            finally{

                //cleanup temp sockets if failed 
                //main socket gets closed when tcpclient gets closed
 
                //did we connect? 
                if ( !m_Active ) {
                    if (ipv6Socket != null) { 
                        ipv6Socket.Close();
                    }

                    if (ipv4Socket != null) { 
                        ipv4Socket.Close();
                    } 
 

                    // 
                    // The connect failed - rethrow the last error we had
                    //
                    if ( lastex != null )
                        throw lastex; 
                    else
                        throw new SocketException(SocketError.NotConnected); 
                } 
            }
 
            if(Logging.On)Logging.Exit(Logging.Sockets, this, "Connect", null);
        }

        ///  
        ///    
        ///       Connects the Client to the specified port on the specified host. 
        ///     
        /// 
        public void Connect(IPAddress address, int port) { 
            if(Logging.On)Logging.Enter(Logging.Sockets, this, "Connect", address);
            if (m_CleanedUp){
                throw new ObjectDisposedException(this.GetType().FullName);
            } 
            if (address==null) {
                throw new ArgumentNullException("address"); 
            } 
            if (!ValidationHelper.ValidateTcpPort(port)) {
                throw new ArgumentOutOfRangeException("port"); 
            }
            IPEndPoint remoteEP = new IPEndPoint(address, port);
            Connect(remoteEP);
            if(Logging.On)Logging.Exit(Logging.Sockets, this, "Connect", null); 
        }
 
        ///  
        ///    
        ///       Connect the Client to the specified end point. 
        ///    
        /// 
        public void Connect(IPEndPoint remoteEP) {
            if(Logging.On)Logging.Enter(Logging.Sockets, this, "Connect", remoteEP); 
            if (m_CleanedUp){
                throw new ObjectDisposedException(this.GetType().FullName); 
            } 
            if (remoteEP==null) {
                throw new ArgumentNullException("remoteEP"); 
            }
            Client.Connect(remoteEP);
            m_Active = true;
            if(Logging.On)Logging.Exit(Logging.Sockets, this, "Connect", null); 
        }
 
 

        //methods 
        public void Connect(IPAddress[] ipAddresses, int port){
            if(Logging.On)Logging.Enter(Logging.Sockets, this, "Connect", ipAddresses);
            Client.Connect(ipAddresses, port);
            m_Active = true; 
            if(Logging.On)Logging.Exit(Logging.Sockets, this, "Connect", null);
        } 
 

        [HostProtection(ExternalThreading=true)] 
        public IAsyncResult BeginConnect(string host, int port, AsyncCallback requestCallback, object state)
        {
            if(Logging.On)Logging.Enter(Logging.Sockets, this, "BeginConnect", host);
            IAsyncResult result = Client.BeginConnect(host, port, requestCallback, state); 
            if(Logging.On)Logging.Exit(Logging.Sockets, this, "BeginConnect", null);
            return result; 
        } 

        [HostProtection(ExternalThreading=true)] 
        public IAsyncResult BeginConnect(IPAddress address, int port, AsyncCallback requestCallback, object state)
        {
            if(Logging.On)Logging.Enter(Logging.Sockets, this, "BeginConnect", address);
            IAsyncResult result = Client.BeginConnect(address, port, requestCallback, state); 
            if(Logging.On)Logging.Exit(Logging.Sockets, this, "BeginConnect", null);
            return result; 
        } 

        [HostProtection(ExternalThreading=true)] 
        public IAsyncResult BeginConnect(IPAddress[] addresses, int port, AsyncCallback requestCallback, object state)
        {

            if(Logging.On)Logging.Enter(Logging.Sockets, this, "BeginConnect", addresses); 
            IAsyncResult result = Client.BeginConnect(addresses, port, requestCallback, state);
            if(Logging.On)Logging.Exit(Logging.Sockets, this, "BeginConnect", null); 
            return result; 
        }
 
        public void EndConnect(IAsyncResult asyncResult){

            if(Logging.On)Logging.Enter(Logging.Sockets, this, "EndConnect", asyncResult);
            Client.EndConnect(asyncResult); 
            m_Active = true;
            if(Logging.On)Logging.Exit(Logging.Sockets, this, "EndConnect", null); 
        } 

 



        ///  
        ///    
        ///       Returns the stream used to read and write data to the 
        ///       remote host. 
        ///    
        ///  
        public NetworkStream GetStream() {
            if(Logging.On)Logging.Enter(Logging.Sockets, this, "GetStream", "");
            if (m_CleanedUp){
                throw new ObjectDisposedException(this.GetType().FullName); 
            }
            if (!Client.Connected) { 
                throw new InvalidOperationException(SR.GetString(SR.net_notconnected)); 
            }
            if (m_DataStream==null) { 
                m_DataStream = new NetworkStream(Client, true);
            }
            if(Logging.On)Logging.Exit(Logging.Sockets, this, "GetStream", m_DataStream);
            return m_DataStream; 
        }
 
        ///  
        ///    
        ///       Disposes the Tcp connection. 
        ///    
        /// 
        //UEUE
        public void Close() { 
            if(Logging.On)Logging.Enter(Logging.Sockets, this, "Close", "");
            GlobalLog.Print("TcpClient::Close()"); 
            ((IDisposable)this).Dispose(); 
            if(Logging.On)Logging.Exit(Logging.Sockets, this, "Close", "");
        } 

        private bool m_CleanedUp = false;

        protected virtual void Dispose(bool disposing) { 
            if(Logging.On)Logging.Enter(Logging.Sockets, this, "Dispose", "");
            if (m_CleanedUp) { 
                if(Logging.On)Logging.Exit(Logging.Sockets, this, "Dispose", ""); 
                return;
            } 

            if (disposing) {
                IDisposable dataStream = m_DataStream;
                if (dataStream != null) 
                {
                    dataStream.Dispose(); 
                } 
                else
                { 
                    //
                    // if the NetworkStream wasn't created, the Socket might
                    // still be there and needs to be closed. In the case in which
                    // we are bound to a local IPEndPoint this will remove the 
                    // binding and free up the IPEndPoint for later uses.
                    // 
                    Socket chkClientSocket = Client; 
                    if (chkClientSocket!= null) {
                        try { 
                            chkClientSocket.InternalShutdown(SocketShutdown.Both);
                        }
                        finally {
                            chkClientSocket.Close(); 
                            Client = null;
                        } 
                    } 
                }
 
                GC.SuppressFinalize(this);
            }

            m_CleanedUp = true; 
            if(Logging.On)Logging.Exit(Logging.Sockets, this, "Dispose", "");
        } 
 
        /// 
        void IDisposable.Dispose() { 
            Dispose(true);
        }

        ~TcpClient() { 
#if DEBUG
            GlobalLog.SetThreadSource(ThreadKinds.Finalization); 
            using (GlobalLog.SetThreadKind(ThreadKinds.System | ThreadKinds.Async)) { 
#endif
            Dispose(false); 
#if DEBUG
            }
#endif
        } 

        ///  
        ///     
        ///       Gets or sets the size of the receive buffer in bytes.
        ///     
        /// 
        public int ReceiveBufferSize {
            get {
                return numericOption(SocketOptionLevel.Socket, 
                                     SocketOptionName.ReceiveBuffer);
            } 
            set { 
                Client.SetSocketOption(SocketOptionLevel.Socket,
                                  SocketOptionName.ReceiveBuffer, value); 
            }
        }

 
        /// 
        ///     
        ///       Gets or 
        ///       sets the size of the send buffer in bytes.
        ///     
        /// 
        public int SendBufferSize {
            get {
                return numericOption(SocketOptionLevel.Socket, 
                                     SocketOptionName.SendBuffer);
            } 
 
            set {
                Client.SetSocketOption(SocketOptionLevel.Socket, 
                                  SocketOptionName.SendBuffer, value);
            }
        }
 
        /// 
        ///     
        ///       Gets or sets the receive time out value of the connection in seconds. 
        ///    
        ///  
        public int ReceiveTimeout {
            get {
                return numericOption(SocketOptionLevel.Socket,
                                     SocketOptionName.ReceiveTimeout); 
            }
            set { 
                Client.SetSocketOption(SocketOptionLevel.Socket, 
                                  SocketOptionName.ReceiveTimeout, value);
            } 
        }

        /// 
        ///     
        ///       Gets or sets the send time out value of the connection in seconds.
        ///     
        ///  
        public int SendTimeout {
            get { 
                return numericOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout);
            }

            set { 
                Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, value);
            } 
        } 

        ///  
        ///    
        ///       Gets or sets the value of the connection's linger option.
        ///    
        ///  
        public LingerOption LingerState {
            get { 
                return (LingerOption)Client.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger); 
            }
            set { 
                Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, value);
            }
        }
 
        /// 
        ///     
        ///       Enables or disables delay when send or receive buffers are full. 
        ///    
        ///  
        public bool NoDelay {
            get {
                return numericOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay) != 0 ? true : false;
            } 
            set {
                Client.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, value ? 1 : 0); 
            } 
        }
 
        private void initialize() {
            //
            // IPv6: Use the address family from the constructor (or Connect method)
            // 
            Client = new Socket(m_Family, SocketType.Stream, ProtocolType.Tcp);
            m_Active = false; 
        } 

        private int numericOption(SocketOptionLevel optionLevel, SocketOptionName optionName) { 
            return (int)Client.GetSocketOption(optionLevel, optionName);
        }

    }; // class TCPClient 

 
} // namespace System.Net.Sockets 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK