/// <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); }