/*------------------------------------------------------------------------- // UNCLASSIFIED /*------------------------------------------------------------------------- RAYTHEON PROPRIETARY: THIS DOCUMENT CONTAINS DATA OR INFORMATION PROPRIETARY TO RAYTHEON COMPANY AND IS RESTRICTED TO USE ONLY BY PERSONS AUTHORIZED BY RAYTHEON COMPANY IN WRITING TO USE IT. DISCLOSURE TO UNAUTHORIZED PERSONS WOULD LIKELY CAUSE SUBSTANTIAL COMPETITIVE HARM TO RAYTHEON COMPANY'S BUSINESS POSITION. NEITHER SAID DOCUMENT NOR ITS CONTENTS SHALL BE FURNISHED OR DISCLOSED TO OR COPIED OR USED BY PERSONS OUTSIDE RAYTHEON COMPANY WITHOUT THE EXPRESS WRITTEN APPROVAL OF RAYTHEON COMPANY. THIS PROPRIETARY NOTICE IS NOT APPLICABLE IF DELIVERED TO THE U.S. GOVERNMENT. UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY. -------------------------------------------------------------------------*/ using System; using System.Net; using System.Net.NetworkInformation; using System.Net.Sockets; using System.Text.RegularExpressions; namespace Raytheon.Instruments.EthernetSockets { /// /// Class for controlling a TCP client communication device /// public class TcpClient { #region PrivateClassMembers private Socket _sock; private string _remoteAddress; private int _remotePort; private IPEndPoint _remoteEP = null; private IPAddress _ipAddress = null; private object _syncObj = new object(); #endregion #region Public Functions /// /// Constructor /// /// /// public TcpClient(string remoteAddress, int remotePort) { _remoteAddress = remoteAddress; _remotePort = remotePort; } /// /// initialize instrument /// public void Initialize() { // if remoteAddress is a hostname if (!IPAddress.TryParse(_remoteAddress, out _ipAddress)) { string preferredSubnet = ""; IPHostEntry host = Dns.GetHostEntry(_remoteAddress); foreach (IPAddress ip in host.AddressList) { AddressFamily af = ip.AddressFamily; if (af == AddressFamily.InterNetwork) { if (preferredSubnet != String.Empty) { if (Regex.IsMatch(ip.ToString(), preferredSubnet, RegexOptions.IgnoreCase)) _ipAddress = ip; } else _ipAddress = ip; if (_ipAddress != null) break; } } } if (_ipAddress != null) { if (_remoteEP == null) _remoteEP = new IPEndPoint(_ipAddress, _remotePort); } else throw new Exception($"Unable to create IPEndPoint to {_remoteAddress}, port {_remotePort}"); if (_sock == null) _sock = new Socket(_ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp); } /// /// Connect to remote host /// /// public void Connect() { lock (_syncObj) { try { if (!_sock.Connected && IsRemoteHostAlive()) _sock.Connect(_remoteEP); } catch (ObjectDisposedException) { _sock = new Socket(_ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp); if (IsRemoteHostAlive()) _sock.Connect(_remoteEP); } catch (Exception) { throw; } } } /// /// Disconnect from remote host /// /// public void Disconnect() { lock (_syncObj) { if (_sock.Connected) { _sock.Shutdown(SocketShutdown.Both); _sock.Disconnect(true); _sock.Close(); } } } /// /// Ping if remote host is alive /// /// true/false bool IsRemoteHostAlive() { bool isRemoteHostAlive = true; //Do a ping test to see if the server is reachable try { Ping pingTest = new Ping(); PingReply reply = pingTest.Send(_ipAddress); if (reply.Status != IPStatus.Success) isRemoteHostAlive = false; } catch (PingException) { isRemoteHostAlive = false; } //See if the tcp state is ok if (_sock.Poll(5000, SelectMode.SelectRead) && (_sock.Available == 0)) { isRemoteHostAlive = false; } return isRemoteHostAlive; } /// /// Read data from the device. /// /// /// /// The number of bytes read public uint Read(ref byte[] dataBuf) { int bytesRec = 0; lock (_syncObj) { try { bytesRec = _sock.Receive(dataBuf); } catch (SocketException) { bytesRec = 0; } } return (uint)bytesRec; } /// /// Sets the read timeout /// /// public void SetReadTimeout(uint timeoutMs) { _sock.ReceiveTimeout = (int)timeoutMs; } /// /// Write data to device. /// /// /// The number of bytes written public uint Write(byte[] dataBuf, uint numBytesToWrite) { int bytesWritten = 0; lock (_syncObj) { try { bytesWritten = _sock.Send(dataBuf, (int)numBytesToWrite, SocketFlags.None); } catch (SocketException) { bytesWritten = 0; } } return (uint)bytesWritten; } #endregion } }