using System; using System.Net.Sockets; using System.Text; using System.Threading; using System.Threading.Tasks; namespace Inno.Communication.TCP { public class TcpClientConnector : IDisposable { private TcpClient _client; private NetworkStream _stream; public bool IsConnected => _client != null && _client.Connected; public async Task ConnectAsync(string host, int port, int timeout, CancellationToken token) { _client = new TcpClient(); var connectTask = _client.ConnectAsync(host, port); if (await Task.WhenAny(connectTask, Task.Delay(timeout, token)) == connectTask) { await connectTask; try { _stream = _client.GetStream(); } catch { _client.Dispose(); throw; } } else { _client.Dispose(); throw new TimeoutException(); } } public async Task WriteAsync(byte[] data, CancellationToken token) { if (_stream == null) throw new InvalidOperationException("Not connected"); await _stream.WriteAsync(data, 0, data.Length, token); } public async Task WriteAsync(string message, Encoding encoding, CancellationToken token) { if (_stream == null) throw new InvalidOperationException("Not connected"); byte[] data = encoding.GetBytes(message); await WriteAsync(data, token); } public async Task ReadAsync(byte[] buffer, CancellationToken token) { if (_stream == null) throw new InvalidOperationException("Not connected"); return await _stream.ReadAsync(buffer, 0, buffer.Length, token); } public void Dispose() { _stream?.Dispose(); _client?.Dispose(); } } }