using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; using System.Threading.Tasks; namespace TelnetCommunicator.Telnet { public enum TelnetMode { Continuously = 0, Once, } public class AsyncSocketTelnetClient { public event EventHandler MessageCallback; private Socket _socket; private Thread _readThread; public async Task Connect(string ip, int port = 23, TelnetMode mode = TelnetMode.Continuously) { try { Close(); _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); _socket.ReceiveTimeout = 1000; IPAddress ipAddress = Dns.GetHostAddresses(ip)[0]; IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, port); await _socket.ConnectAsync(ipEndPoint); switch (mode) { case TelnetMode.Continuously: _readThread = new Thread(ReadAsync); break; case TelnetMode.Once: _readThread = new Thread(ReadAsyncOnce); break; } _readThread.Start(); } catch (Exception) { throw; } } private async void ReadAsync() { try { StringBuilder sb = new StringBuilder(); byte[] readBuffer = new byte[1024]; while (true) { int readByte = _socket == null ? 0 : await _socket.ReceiveAsync(readBuffer, SocketFlags.None); if (readByte < 1) break; string data = Encoding.ASCII.GetString(readBuffer, 0, readByte); sb.Append(data); if (!data.EndsWith("\r\n>")) continue; // 에코 삭제 string read = sb.ToString(); int rnIdx = read.IndexOf("\r\n"); read = read.Substring(rnIdx + 1); if (this.MessageCallback != null) this.MessageCallback(this, read); sb.Clear(); } } catch (Exception) { throw; } } private async void ReadAsyncOnce() { try { StringBuilder sb = new StringBuilder(); byte[] readBuffer = new byte[1024]; while (true) { int readByte = _socket == null ? 0 : await _socket.ReceiveAsync(readBuffer, SocketFlags.None); if (readByte < 1) { if (sb.Length > 0 && this.MessageCallback != null) this.MessageCallback(this, sb.ToString()); break; } string data = Encoding.ASCII.GetString(readBuffer, 0, readByte); sb.Append(data); if (!data.EndsWith("\r\n>")) continue; // 에코 삭제 string read = sb.ToString(); int rnIdx = read.IndexOf("\r\n"); read = read.Substring(rnIdx + 1); if (this.MessageCallback != null) this.MessageCallback(this, read); sb.Clear(); } Close(); } catch (Exception) { throw; } } public async Task SendMessage(string message) { if (_socket == null) return; try { message += "\r\n"; byte[] sendBuffer = Encoding.ASCII.GetBytes(message); await _socket.SendAsync(sendBuffer, SocketFlags.None); } catch (Exception) { throw; } } public void Close() { if (_socket == null) return; try { _socket.Shutdown(SocketShutdown.Both); //_readThread.Abort(); _socket.Close(); _socket.Disconnect(true); _socket.Dispose(); } catch (Exception) { throw; } } } }