using AwInitilizer.Interface; using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading.Tasks; namespace AwInitilizer.Assist { public class TcpSerializer : Interface.ISerialPort { public event EventHandler OnDataReceived; public event PropertyChangedEventHandler PropertyChanged; public string IP { get; private set; } private ConnectStatus _ConnectStatus = ConnectStatus.Cleared; public ConnectStatus ConnectStatus { get => _ConnectStatus; set { if (_ConnectStatus != value) { _ConnectStatus = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("ConnectStatus")); } } } private IPAddress iPAddress; private IPEndPoint iPEndPoint; private Socket tcpSocket; public TcpSerializer(string ip = "192.168.1.10",int port = 8234) { IP = ip; iPAddress = IPAddress.Parse(ip); iPEndPoint = new IPEndPoint(iPAddress, port); } public async Task OpenAsync() { await Conenct(); } public void Open() { _ = Conenct(); } public void Close() { ConnectStatus = ConnectStatus.DisConnected; try { tcpSocket?.Close(); tcpSocket?.Dispose(); } catch { } } public void WriteData(byte[] msg) { if (ConnectStatus != ConnectStatus.Connected) return; tcpSocket.Send(msg); } private async Task Conenct() { ConnectStatus = ConnectStatus.Connecting; tcpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); tcpSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); var connectTask = tcpSocket.ConnectAsync(iPEndPoint); //var asyncResult = tcpSocket.BeginConnect(iPEndPoint, OnTcpConnectComplete, null); //await Task.Delay(2 * 1000); await Task.WhenAny(connectTask, Task.Delay(2 * 1000)); if (tcpSocket.Connected) { ConnectStatus = ConnectStatus.Connected; var stateObject = new StateObject(bufferSize: 512, tcpSocket); WaitForData(stateObject); } else { ConnectStatus = ConnectStatus.ConnectionFail; //Try Clear - disconnect Close(); } } private void OnTcpConnectComplete(IAsyncResult ar) { if (tcpSocket.Connected) { ConnectStatus = ConnectStatus.Connected; var stateObject = new StateObject(bufferSize: 512, tcpSocket); WaitForData(stateObject); } else { ConnectStatus = ConnectStatus.ConnectionFail; } } private void WaitForData(StateObject stateObject) { try { var soc = stateObject.sSocket; if (!soc.Connected) { return; } IAsyncResult iar = soc.BeginReceive( stateObject.sBuffer, 0, stateObject.sBuffer.Length, SocketFlags.None, new AsyncCallback(ReveiveCallBack), stateObject); } catch (Exception e) { if (e != null) { if (e.Message != null) Console.WriteLine(e.Message); if (e.StackTrace != null) Console.WriteLine(e.StackTrace); } } } private void ReveiveCallBack(IAsyncResult ar) { StateObject stateObject = (StateObject)ar.AsyncState; if (!stateObject.sSocket.Connected) { //server Diconnected HandleDisconnected(); return; } int bytesReceived; try { bytesReceived = stateObject.sSocket.EndReceive(ar); } catch (SocketException e) { if (e != null) { if (e.Message != null) System.Diagnostics.Debug.WriteLine(e.Message); if (e.StackTrace != null) System.Diagnostics.Debug.WriteLine(e.StackTrace); } //server Diconnected HandleDisconnected(); return; } if (bytesReceived == 0) { stateObject.sSocket.Disconnect(true); HandleDisconnected(); return; } byte[] receivedBytes = new byte[bytesReceived]; Array.Copy(stateObject.sBuffer, 0, receivedBytes, 0, bytesReceived); OnDataReceived?.Invoke(this, receivedBytes); //continue receive WaitForData(stateObject); } private void HandleDisconnected() { Close(); } } internal class StateObject { public byte[] sBuffer; public Socket sSocket; public StateObject(int bufferSize, Socket sock, int timeOutMilliSecond = -1) { sBuffer = new byte[bufferSize]; sSocket = sock; } } }