using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading.Tasks; using System.Timers; namespace EPD.Data { public class SocketClientWrapper : IDisposable { public Action OnConnected; public Action OnDisconnected; public Action OnDataChanged; private static Object _lockerSender = new Object(); private BlockingCollection SetPointCommandQueue = new BlockingCollection(); Timer timer = new Timer(500); public class ClientStateObject { public const int BufferSize = 16384; public Socket WorkSocket = null; public byte[] CacheBufferByteData = new byte[BufferSize]; } private Socket socket; public bool IsConnected { get { return socket != null && socket.Connected; } } public SocketClientWrapper() { timer.Elapsed += Timer_Elapsed; timer.Enabled = true; } private void Timer_Elapsed(object sender, ElapsedEventArgs e) { if (SetPointCommandQueue.Count > 0) { var byteData = SetPointCommandQueue.Take(); socket.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), socket); } } ~SocketClientWrapper() { Dispose(); } /// /// /// /// 127.0.0.1:15000 public void Connect(string ip, int port) { try { var remote = new IPEndPoint(IPAddress.Parse(ip), port); Dispose(); socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); socket.BeginConnect(remote, ConnectCallback, socket); //Task.Run(() => //{ // while (SetPointCommandQueue.Count > 0) // { // System.Threading.Thread.Sleep(500); // } // System.Threading.Thread.Sleep(500); //}); } catch (Exception ex) { System.Diagnostics.Trace.Write("Error in Connect, " + ex.Message); } } private void ConnectCallback(IAsyncResult ar) { try { var client = (Socket)ar.AsyncState; client.EndConnect(ar); if (OnConnected != null) OnConnected(); System.Diagnostics.Trace.Write("Connected"); var state = new ClientStateObject(); state.WorkSocket = socket; socket.BeginReceive(state.CacheBufferByteData, 0, ClientStateObject.BufferSize, 0, ReceiveCallback, state); } catch (Exception ex) { System.Diagnostics.Trace.Write("Error in ConnectCallback, " + ex.Message); } } public void Disconnect() { Dispose(); if (OnDisconnected != null) OnDisconnected(); } private void ReceiveCallback(IAsyncResult ar) { try { if (!IsConnected) return; ClientStateObject state = (ClientStateObject)ar.AsyncState; Socket client = state.WorkSocket; int bytesRead = client.EndReceive(ar); if (bytesRead > 0) { if (OnDataChanged != null) OnDataChanged(state.CacheBufferByteData, 0, bytesRead); client.BeginReceive(state.CacheBufferByteData, 0, ClientStateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state); } } catch (Exception ex) { System.Diagnostics.Trace.Write("Error in ReceiveCallback, " + ex.Message); Disconnect(); } } public bool Send(byte[] byteData) { try { if (!IsConnected) return false; lock (_lockerSender) { SetPointCommandQueue.Add(byteData); //socket.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), socket); } return true; } catch (Exception ex) { System.Diagnostics.Trace.Write("Error int Write, " + ex.Message); } return false; } private void SendCallback(IAsyncResult ar) { try { lock (_lockerSender) { Socket client = (Socket)ar.AsyncState; client.EndSend(ar); } } catch (Exception ex) { System.Diagnostics.Trace.Write("Error in SendCallback, " + ex.Message); } } public void Dispose() { try { if (socket != null) { if (IsConnected) { socket.Shutdown(SocketShutdown.Both); } socket.Close(); socket.Dispose(); socket = null; } } catch (Exception ex) { System.Diagnostics.Trace.Write("Error in Dispose, " + ex.Message); } } } }