using System; using System.Collections.Generic; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; using Inspectron.HawkEye.UDPB; using Newtonsoft.Json; namespace Inspectron.HawkEye.Protocol { public class ImageClientTCP : IDisposable { private static readonly object connectionLock = new object(); private readonly IPEndPoint _endpoint; private readonly IPAddress _adapter; private TcpListener _imageSocket; private TcpClient _commandSocket; private bool _isConnected = true; public ImageClientTCP(IPEndPoint endpoint,IPAddress adapter) { _endpoint = endpoint; _adapter = adapter; } public void Dispose() { _isConnected = false; _commandSocket.Dispose(); } byte[] _commandBuffer = new byte[1500]; private TcpClient _lastClient; public bool SupportsCalibration { get; set; } public void Connect() { lock (connectionLock) { _commandSocket=new TcpClient(new IPEndPoint(_adapter, 0)); Console.WriteLine($"Bind on {_adapter?.ToString()}"); _commandSocket.Connect(_endpoint); var port = UDPBSocket.FindFreePort(_adapter); Console.WriteLine("Connected"); _imageSocket = new TcpListener(_adapter, port); _imageSocket.Start(); Console.WriteLine("TCP started"); var bytesPort = BitConverter.GetBytes(port); _commandSocket.Client.SendData(new[] {(byte) ECommand.Connect, bytesPort[0], bytesPort[1], bytesPort[2], bytesPort[3]}); var receivedLen = _commandSocket.Client.Receive(_commandBuffer); Console.WriteLine("received answer length:"+receivedLen); var b = new byte[receivedLen - 1]; Array.Copy(_commandBuffer, 1, b, 0, b.Length); var settingsString = Encoding.UTF8.GetString(b); SettingsReceived(JsonConvert.DeserializeObject(settingsString)); if (SupportsCalibration) { _commandSocket.Client.SendData(new[] {(byte) ECommand.GetCalibration}); receivedLen = _commandSocket.Client.Receive(_commandBuffer); if (_commandBuffer[0] == (byte) ECommand.OK) { Console.WriteLine($"calibration received {receivedLen} bytes"); var c = new byte[receivedLen - 1]; Array.Copy(_commandBuffer, 1, c, 0, c.Length); var calibrationString = Encoding.UTF8.GetString(c); CalibrationReceived(JsonConvert.DeserializeObject>>(calibrationString)); } else { Console.WriteLine("no calibration received"); } } var th = new Thread(ReceiveLoop); th.Start(); } } public event Action ImageReceived = delegate { }; public event Action SettingsReceived = delegate { }; public event Action>> CalibrationReceived = delegate { }; public void Trigger() { _commandSocket.Client.SendData(new[] {(byte) ECommand.Trigger}); } public void ApplySettings(CameraSettings cameraSettings) { var data = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(cameraSettings)); var databytes = new byte[1000]; databytes[0] = (byte) ECommand.Settings; Array.Copy(data, 0, databytes, 1, data.Length); _commandSocket.Client.SendData(databytes); byte[] ok = new byte[1]; _commandSocket.Client.Receive(ok); } public void StartContinuous() { _commandSocket.Client.SendData(new[] {(byte) ECommand.StartContinuous}); } public void StopContinuous() { _commandSocket.Client.SendData(new[] {(byte) ECommand.StopContinuous}); } public void SaveSettingsOnCamera() { _commandSocket.Client.SendData(new[] {(byte) ECommand.SaveSettings}); } private byte[] _imageBuffer = new byte[10*1024*1024]; private void ReceiveLoop() { while (_isConnected) { _lastClient = _imageSocket.AcceptTcpClient(); while (true) { int received=0; try { _lastClient.Client.Receive(_imageBuffer, 0, 1, SocketFlags.None); Process(_imageBuffer); } catch { break; } } } } public void SaveCalibration(List> calibration) { var data = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(calibration)); var databytes = new byte[1500]; databytes[0] = (byte)ECommand.SaveCalibration; Array.Copy(data, 0, databytes, 1, data.Length); _commandSocket.Client.SendData(databytes); byte[] ok = new byte[1]; _commandSocket.Client.Receive(ok); } private void Process(byte[] data) { switch ((EData) data[0]) { case EData.Image: _lastClient.Client.Receive(_imageBuffer, 1, 4, SocketFlags.None); var imageSize = BitConverter.ToInt32(_imageBuffer,1); var received = 0; do { received += _lastClient.Client.Receive(_imageBuffer, 5+ received, imageSize- received, SocketFlags.None); } while (received < imageSize); var b = new byte[imageSize]; Array.Copy(data, 5, b, 0, b.Length); ImageReceived(b); break; default: throw new ArgumentOutOfRangeException(); } } } }