예제 #1
0
        /// <summary>
        /// Initialize the Watson TCP client.
        /// </summary>
        /// <param name="serverIp">The IP address or hostname of the server.</param>
        /// <param name="serverPort">The TCP port on which the server is listening.</param>
        /// <param name="serverConnected">Function to be called when the server connects.</param>
        /// <param name="serverDisconnected">Function to be called when the connection is severed.</param>
        /// <param name="messageReceived">Function to be called when a message is received.</param>
        /// <param name="debug">Enable or debug logging messages.</param>
        public WatsonTcpClient(
            string serverIp,
            int serverPort,
            Func <bool> serverConnected,
            Func <bool> serverDisconnected,
            Func <byte[], bool> messageReceived,
            bool debug)
        {
            if (String.IsNullOrEmpty(serverIp))
            {
                throw new ArgumentNullException(nameof(serverIp));
            }

            if (serverPort < 1)
            {
                throw new ArgumentOutOfRangeException(nameof(serverPort));
            }

            _ServerIp   = serverIp;
            _ServerPort = serverPort;

            _ServerConnected    = serverConnected;
            _ServerDisconnected = serverDisconnected;
            _MessageReceived    = messageReceived ?? throw new ArgumentNullException(nameof(messageReceived));
            _Encrypter          = new Encrypter("keyfile.ppsk");

            _Debug = debug;

            _SendLock = new SemaphoreSlim(1);

            _Client = new TcpClient();
            IAsyncResult ar = _Client.BeginConnect(_ServerIp, _ServerPort, null, null);
            WaitHandle   wh = ar.AsyncWaitHandle;

            try
            {
                if (!ar.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(5), false))
                {
                    _Client.Close();
                    throw new TimeoutException("Timeout connecting to " + _ServerIp + ":" + _ServerPort);
                }

                _Client.EndConnect(ar);

                _SourceIp   = ((IPEndPoint)_Client.Client.LocalEndPoint).Address.ToString();
                _SourcePort = ((IPEndPoint)_Client.Client.LocalEndPoint).Port;
                _Connected  = true;
            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                wh.Close();
            }

            if (_ServerConnected != null)
            {
                Task.Run(() => _ServerConnected());
            }

            _TokenSource = new CancellationTokenSource();
            _Token       = _TokenSource.Token;
            Task.Run(async() => await DataReceiver(_Token), _Token);
        }