You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

172 lines
4.7 KiB

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<string> 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;
}
}
}
}