예제 #1
0
        /// <summary>
        /// Connect a stream according to the settings provided.
        /// </summary>
        /// <param name="settings">Network settings to use to connect the stream</param>
        /// <returns>A <see cref="CStreamClientIO"/> object is evrything went fine, null otherwise</returns>
        public static CStreamClientIO Connect(CStreamClientSettings settings)
        {
            CStreamClientIO stream = null;

            try
            {
                // determine whether v4 or v6 IP addresse
                IPAddress ip        = IPAddress.Parse(settings.IP);
                bool      v6        = AddressFamily.InterNetworkV6 == ip.AddressFamily;
                TcpClient tcpclient = new TcpClient(v6 ? AddressFamily.InterNetworkV6 : AddressFamily.InterNetwork);
                try
                {
                    CLog.DEBUG($"{MethodBase.GetCurrentMethod().Module.Name}.{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}", $"About to connect to {settings.FullIP}");
                    tcpclient.Connect(settings.Address, (int)settings.Port);
                    tcpclient.SendBufferSize    = (tcpclient.SendBufferSize >= settings.SendBufferSize ? tcpclient.SendBufferSize : settings.SendBufferSize + 1);
                    tcpclient.ReceiveBufferSize = (tcpclient.ReceiveBufferSize >= settings.ReceiveBufferSize ? tcpclient.SendBufferSize : settings.ReceiveBufferSize);
                    tcpclient.SendTimeout       = settings.SendTimeout * CStreamSettings.ONESECOND;
                    tcpclient.ReceiveTimeout    = settings.ReceiveTimeout * CStreamSettings.ONESECOND;
                    // Create an SSL stream that will close the client's stream.
                    stream = new CStreamClientIO(tcpclient, settings);
                }
                catch (Exception ex)
                {
                    CLog.AddException($"{MethodBase.GetCurrentMethod().Module.Name}.{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}", ex);
                    tcpclient.Close();
                }
            }
            catch (Exception ex)
            {
                CLog.AddException($"{MethodBase.GetCurrentMethod().Module.Name}.{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}", ex);
            }
            return(stream);
        }
예제 #2
0
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        bool TestConnect(char c)
        {
            StartServer(c);

            CStreamClientSettings settings = new CStreamClientSettings()
            {
                AllowedSslErrors = SslPolicyErrors.RemoteCertificateNotAvailable | SslPolicyErrors.RemoteCertificateNameMismatch | SslPolicyErrors.RemoteCertificateChainErrors,
                //IP = CStream.Localhost(),
                IP         = "127.0.0.1",
                Port       = Port,
                ServerName = UseSSL ? "hello world" : null,
            };
            CStreamClientIO clientIO = CStream.Connect(settings);

            if (null != clientIO)
            {
                clientIO.Send("hello");
                Console.ReadKey();
                Console.WriteLine($"Client connected: {clientIO.Connected}");
                Console.ReadKey();
                StopServer(c);
                Console.ReadKey();
                Console.WriteLine($"Client connected: {clientIO.Connected}");
                clientIO.Close();
            }
            return(true);
        }
예제 #3
0
        /// <summary>
        /// Open the adequate stream to the server.
        /// </summary>
        /// <param name="client">TCP client to use to open the stream</param>
        /// <param name="settings">Settings to use when manipulating the stream</param>
        public CStreamClientIO(TcpClient client, CStreamClientSettings settings) : base(client, settings.LengthBufferSize)
        {
            if (settings.IsValid)
            {
                Settings = settings;
                // determine the kind of link to use
                if (Settings.UseSsl)
                {
                    sslStream = new SslStream(client.GetStream(), false, new RemoteCertificateValidationCallback(ValidateServerCertificate), null);
                    int tmo = client.ReceiveTimeout * 1000;
                    client.ReceiveTimeout = 5000;
                    try
                    {
                        // authenticate aginst the server

#if NET35
                        // check if TLS is supported
                        bool useTLS = false;
                        try
                        {
                            RegistryKey key   = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP\v3.5");
                            object      value = (null != key ? key.GetValue("SP") : null);
                            useTLS = (null != value && 1 <= (int)value);
                        }
                        catch (Exception ex) { }
                        CLog.Add($".NET 3.5 {(useTLS ? "using TLS 1.2" : "not using TLS")}", TLog.INFOR);
                        if (useTLS)
                        {
                            sslStream.AuthenticateAsClient(Settings.ServerName, null, (System.Security.Authentication.SslProtocols) 3072, false);
                        }
                        else
                        {
                            sslStream.AuthenticateAsClient(Settings.ServerName);
                        }
#else
                        sslStream.AuthenticateAsClient(Settings.ServerName);
#endif
                    }
                    catch (Exception ex)
                    {
                        CLog.AddException($"{MethodBase.GetCurrentMethod().Module.Name}.{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}", ex);
                        sslStream = null;
                        throw;
                    }
                    finally
                    {
                        client.ReceiveTimeout = tmo;
                    }
                }
                else
                {
                    networkStream = client.GetStream();
                }
            }
            else
            {
                throw new Exception("Invalid client stream settings.");
            }
        }
예제 #4
0
        private static CStreamClientIO ConnectToSend(CStreamClientSettings settings, string request)
        {
            // adjust buffer size according to buffer to send
            int fullBufferSize = request.Length + (int)settings.LengthBufferSize;

            settings.SendBufferSize = (settings.SendBufferSize > fullBufferSize ? settings.SendBufferSize : fullBufferSize + 1);
            return(Connect(settings));
        }
예제 #5
0
        private static CStreamClientIO ConnectToSend(CStreamClientSettings settings, byte[] request, bool addSizeHeader)
        {
            // adjust buffer size according to buffer to send
            int fullBufferSize = (addSizeHeader ? request.Length + (int)settings.LengthBufferSize : request.Length);

            settings.SendBufferSize = (settings.SendBufferSize > fullBufferSize ? settings.SendBufferSize : fullBufferSize + 1);
            return(Connect(settings));
        }
예제 #6
0
        /// <summary>
        /// This function prevents using any size header, using CR+LF as an EOT
        /// </summary>
        /// <param name="settings"></param>
        /// <param name="request"></param>
        /// <param name="EOT"></param>
        /// <returns></returns>
        public static bool ConnectSendLine(CStreamClientSettings settings, string request, string EOT = CStreamIO.CRLF)
        {
            if (string.IsNullOrEmpty(request))
            {
                return(false);
            }
            CStreamClientIO stream = ConnectToSend(settings, request);

            if (null != stream)
            {
                bool fOK = SendLine(stream, request, EOT);
                Disconnect(stream);
                return(fOK);
            }
            return(false);
        }
예제 #7
0
        /// <summary>
        /// Connect (<see cref="Connect(CStreamClientSettings)"/>) and send data (<see cref="Send(CStreamIO, byte[], bool)"/> and <see cref="Send(CStreamIO, string)"/>).
        /// </summary>
        /// <param name="settings">The settings to use for sending data</param>
        /// <param name="request">A array of bytes to send</param>
        /// <param name="addSizeHeader">Indicates whether a buffer size block must be added before the buffer to send</param>
        /// <returns>An arry of bytes received in response or if an error occured. In case of a client only request, the function returns the request, as no reply can be returned, if everything went right</returns>
        public static bool ConnectSend(CStreamClientSettings settings, byte[] request, bool addSizeHeader)
        {
            if (null == request || 0 == request.Length)
            {
                return(false);
            }
            CStreamClientIO stream = ConnectToSend(settings, request, addSizeHeader);

            if (null != stream)
            {
                bool fOK = Send(stream, request, addSizeHeader);
                Disconnect(stream);
                return(fOK);
            }
            return(false);
        }
예제 #8
0
        /// <summary>
        /// This function prevents using any size header, using CR+LF as an EOT
        /// </summary>
        /// <param name="settings"></param>
        /// <param name="request"></param>
        /// <param name="error"></param>
        /// <param name="EOT"></param>
        /// <returns></returns>
        public static string ConnectSendReceiveLine(CStreamClientSettings settings, string request, out bool error, string EOT = CStreamIO.CRLF)
        {
            error = false;
            if (string.IsNullOrEmpty(request))
            {
                return(null);
            }
            CStreamClientIO stream = ConnectToSend(settings, request);

            if (null != stream)
            {
                string reply = SendReceiveLine(stream, request, out error, EOT);
                Disconnect(stream);
                return(reply);
            }
            return(null);
        }
예제 #9
0
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        bool SendData(char c)
        {
            CStreamClientSettings settings = new CStreamClientSettings()
            {
                AllowedSslErrors = SslPolicyErrors.RemoteCertificateNotAvailable | SslPolicyErrors.RemoteCertificateNameMismatch | SslPolicyErrors.RemoteCertificateChainErrors,
                //IP = CStream.Localhost(),
                IP         = "127.0.0.1",
                Port       = Port,
                ServerName = UseSSL ? "hello world" : null,
            };

            Console.Write("Message to send: ");
            string request = Console.ReadLine();
            string reply   = null;

            if (null != (reply = CStream.ConnectSendReceive(settings, string.IsNullOrEmpty(request) ? DateTime.Now.ToString() : request, out int size, out bool error)))
            {
                Console.WriteLine("CLIENT RECEIVED: " + reply);
            }
예제 #10
0
        /// <summary>
        /// Connect (<see cref="Connect(CStreamClientSettings)"/>), send (<see cref="Send(CStreamIO, byte[], bool)"/> and <see cref="Send(CStreamIO, string)"/>) and receive (<see cref="Receive(CStreamIO, out int, out bool, bool)"/> and <see cref="Receive(CStreamIO, out int, out bool)"/>) data.
        /// </summary>
        /// <param name="settings">The settings to use for sending data</param>
        /// <param name="request">A array of bytes to send</param>
        /// <param name="addSizeHeader">Indicates whether a buffer size block must be added before the buffer to send</param>
        /// <param name="announcedSize">The size of the reply as announced by the sender</param>
        /// <param name="error">True indicates the function ended up with a error, false otherwise</param>
        /// <returns>An arry of bytes received in response or if an error occured. In case of a client only request, the function returns the request, as no reply can be returned, if everything went right</returns>
        public static byte[] ConnectSendReceive(CStreamClientSettings settings, byte[] request, bool addSizeHeader, out int announcedSize, out bool error)
        {
            byte[] reply = null;
            error         = false;
            announcedSize = 0;
            if (null == request || 0 == request.Length)
            {
                return(null);
            }
            CStreamClientIO stream = ConnectToSend(settings, request, addSizeHeader);

            if (null != stream)
            {
                if (Send(stream, request, addSizeHeader))
                {
                    reply = Receive(stream, out announcedSize, out error, addSizeHeader);
                }
                Disconnect(stream);
            }
            return(reply);
        }
예제 #11
0
 /// <summary>
 /// Refer to <see cref="ConnectSendReceive(CStreamClientSettings, byte[], bool, out int, out bool)"/>
 /// </summary>
 /// <param name="settings"></param>
 /// <param name="request"></param>
 /// <param name="announcedSize"></param>
 /// <param name="error"></param>
 /// <returns></returns>
 public static string ConnectSendReceive(CStreamClientSettings settings, string request, out int announcedSize, out bool error)
 {
     byte[] reply = ConnectSendReceive(settings, Encoding.UTF8.GetBytes(request), true, out announcedSize, out error);
     return(null != reply ? Encoding.UTF8.GetString(reply) : null);
 }
예제 #12
0
 /// <summary>
 /// Refer to <see cref="ConnectSend(CStreamClientSettings, byte[], bool)"/>
 /// </summary>
 /// <param name="settings"></param>
 /// <param name="request"></param>
 /// <returns></returns>
 public static bool ConnectSend(CStreamClientSettings settings, string request)
 {
     return(ConnectSend(settings, string.IsNullOrEmpty(request) ? null : Encoding.UTF8.GetBytes(request), true));
 }