使用
TcpClient 类 (System.Net.Sockets) | Microsoft Learn
主要类:
public class MyTcpClient : IDisposable
{
private TcpClient _tcpClient = null;
private NetworkStream _stream = null;
private volatile bool _isConnect;
private int _port;
private string _ip;
private int _connectTimeout = 15000;
public string EnCodeName { get; set; } = "UTF8";
public event EventHandler<object> Received;
public Action<string> _onReceived = null;
public Action<bool> _onIsConnect = null;
private CancellationTokenSource cts = null;
private TaskCompletionSource<string> source = null;
public bool IsConnect
{
get => _isConnect;
set => _isConnect = value;
}
public static Encoding GetEncoding(string encodingString)
{
Encoding encoding = Encoding.Default;
switch (encodingString)
{
case "Default":
encoding = Encoding.Default;
break;
case "UTF8":
encoding = Encoding.UTF8;
break;
case "ASCII":
encoding = Encoding.ASCII;
break;
default:
break;
}
return encoding;
}
/// <summary>
/// 获取IP地址
/// </summary>
/// <returns></returns>
//public static YOIResult<List<string>> GetIPAddress()
//{
// List<string> listIP = new List<string>();
// var host = Dns.GetHostEntry(Dns.GetHostName());
// foreach (var ip in host.AddressList)
// {
// if (ip.AddressFamily == AddressFamily.InterNetwork)
// {
// listIP.Add(ip.ToString());
// }
// }
// return new YOIResult<List<string>> { Code = ResultCodeStatus.Success, Data = listIP, Message = "获取IP地址成功" };
//}
public async Task<bool> ConnectAsync(string ip, int port, int timeout = 1000)
{
try
{
_ip = ip;
_port = port;
_connectTimeout = timeout;
_tcpClient = new TcpClient();
try
{
await _tcpClient.ConnectAsync(IPAddress.Parse(_ip), _port).TimeOutEx(_connectTimeout);
}
catch (Exception)
{
_isConnect = false;
return _isConnect;
}
_isConnect = true;
cts = new CancellationTokenSource();
await Task.Run(() =>
{
if (!cts.IsCancellationRequested)
{
try
{
if (_tcpClient != null)
{
ReadMessageAsync();
}
}
catch (Exception)
{
Dispose();
}
}
}, cts.Token);
}
catch (Exception)
{
Dispose();
return _isConnect;
}
return _isConnect;
}
private async void ReadMessageAsync()
{
while (_isConnect)
{
if (_tcpClient != null)
{
if (_tcpClient.Connected)
{
_stream = _tcpClient.GetStream();
//接收数据
byte[] buffer = new byte[1024];
int bytesRead = await _stream.ReadAsync(buffer, 0, buffer.Length);
if (bytesRead <= 0)
{
if (source != null)
{
source.TrySetResult(null);
}
break;
}
else
{
string data = string.Empty;
if (EnCodeName.Contains("HEX"))
{
data = Encoding.UTF8.GetString(buffer, 0, bytesRead);
data = CRC.StringToHexString(data);
}
else
{
data = GetEncoding(EnCodeName).GetString(buffer, 0, bytesRead);
}
string tempMsg = string.Empty;
string clientIP = string.Empty;
if (_tcpClient.Connected && _tcpClient != null)
{
clientIP = _tcpClient.Client.RemoteEndPoint?.ToString();
}
tempMsg = "IP:" + clientIP;
if (source != null)
{
source.TrySetResult(data);
}
// 触发消息接收事件
Received?.Invoke(null, data);
}
}
}
}
}
public bool SendData(string message, string encoding)
{
try
{
if (_tcpClient != null)
{
byte[] data = null;
if (encoding.Contains("HEX"))
{
data = CRC.StringToHexByte(message);
}
else
{
data = GetEncoding(encoding).GetBytes(message);
}
if (_tcpClient.Connected)
{
NetworkStream stream = _tcpClient.GetStream();
stream.Write(data, 0, data.Length);
}
}
else
{
_onIsConnect.Invoke(false);
return false;
}
}
catch (Exception)
{
return false;
}
return true;
}
public bool SendData(string message, string encoding, int timeOut, ref string rev)
{
try
{
if (_tcpClient != null)
{
byte[] data = null;
if (encoding.Contains("HEX"))
{
data = CRC.StringToHexByte(message);
}
else
{
data = GetEncoding(encoding).GetBytes(message);
}
if (_tcpClient.Connected)
{
source = new TaskCompletionSource<string>();
NetworkStream stream = _tcpClient.GetStream();
stream.Write(data, 0, data.Length);
string results = string.Empty;
var task = Task.Run(async () =>
{
try
{
results = await WithTimeout(source.Task, timeOut);
}
catch (TimeoutException)
{
results = string.Empty;
}
});
task.Wait();
rev = results.ToString();
if (string.IsNullOrWhiteSpace(rev))
{
return false;
}
return true;
}
}
else
{
if (_onIsConnect != null)
{
_onIsConnect.Invoke(false);
}
return false;
}
}
catch (Exception)
{
return false;
}
return true;
}
public string GetRemoteEndPoint()
{
if (_tcpClient != null)
{
return _tcpClient.Client.RemoteEndPoint.ToString();
}
return "";
}
public void Dispose()
{
try
{
IsConnect = false;
cts.Cancel();
if (_tcpClient != null)
{
_tcpClient.Close();
_tcpClient = null;
}
}
catch (Exception)
{
}
}
public static async Task<T> WithTimeout<T>(Task<T> task, int timeout)
{
if (await Task.WhenAny(task, Task.Delay(timeout)) == task)
{
return await task;
}
else
{
throw new TimeoutException("Operation timed out.");
}
}
}
public static class TcpCommon
{
public static async Task TimeOutEx(this Task task, int timeout)
{
if (await Task.WhenAny(task, Task.Delay(timeout)) == task)
{
await task;
}
else throw new TimeoutException("TCP连接超时");
}
}