using Common.Attributes;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using static Common.Attributes.ATSCommandAttribute;
namespace DeviceCommand.Base
{
[ATSCommand]
[DeviceCategory("全部驱动")] // 添加分类属性
public class Udp
{
public string RemoteIpAddress { get; set; } = "127.0.0.1";
public int RemotePort { get; set; } = 8080;
public int LocalPort { get; set; } = 0; // 0 表示系统自动分配
public int SendTimeout { get; set; } = 3000;
public int ReceiveTimeout { get; set; } = 3000;
public UdpClient UdpClient { get; set; } = new UdpClient();
///
/// 创建UDP设备对象
///
/// IP地址
/// 端口号
/// 发送超时时间
/// 接收超时时间
public Udp CreateDevice(string ipAddress, int port, int sendTimeout = 3000, int receiveTimeout = 3000)
{
RemoteIpAddress = ipAddress;
RemotePort = port;
SendTimeout = sendTimeout;
ReceiveTimeout = receiveTimeout;
if (LocalPort > 0)
{
UdpClient = new UdpClient(LocalPort);
}
else
{
UdpClient = new UdpClient();
}
UdpClient.Client.SendTimeout = SendTimeout;
UdpClient.Client.ReceiveTimeout = ReceiveTimeout;
return this;
}
///
/// 修改UDP连接参数
///
/// UDP设备对象
/// IP地址
/// 端口号
/// 发送超时时间
/// 接收超时时间
public static void ChangeDeviceConfig(Udp udp, string ipAddress, int port, int sendTimeout = 3000, int receiveTimeout = 3000)
{
udp.RemoteIpAddress = ipAddress;
udp.RemotePort = port;
if (sendTimeout > 0)
{
udp.SendTimeout = sendTimeout;
}
if (receiveTimeout > 0)
{
udp.ReceiveTimeout = receiveTimeout;
}
if (udp.UdpClient != null)
{
udp.UdpClient.Client.SendTimeout = udp.SendTimeout;
udp.UdpClient.Client.ReceiveTimeout = udp.ReceiveTimeout;
}
}
// ————————————————————————
// 功能 78
// ————————————————————————
///
/// UDP连接(功能78)
/// UDP是无连接的,此处主要进行初始化和设置默认远程端点
///
/// UDP设备对象
/// 取消令牌
/// 连接结果
public static async Task ConnectAsync(Udp udp, CancellationToken ct = default)
{
if (udp.UdpClient == null)
{
if (udp.LocalPort > 0)
{
udp.UdpClient = new UdpClient(udp.LocalPort);
}
else
{
udp.UdpClient = new UdpClient();
}
}
udp.UdpClient.Client.SendTimeout = udp.SendTimeout;
udp.UdpClient.Client.ReceiveTimeout = udp.ReceiveTimeout;
var remoteEndpoint = new IPEndPoint(IPAddress.Parse(udp.RemoteIpAddress), udp.RemotePort);
//await udp.UdpClient.ConnectAsync(remoteEndpoint, ct);
return true;
}
///
/// 紧急停止(功能78)
///
/// UDP设备对象
public static void EmergencyStop(Udp udp)
{
Close(udp); // 复用 Close 逻辑
}
// ————————————————————————
// 功能 79
// ————————————————————————
///
/// 设备初始化(功能79)
///
/// UDP设备对象
public static void InitializeDevice(Udp udp)
{
if (udp.UdpClient == null)
{
if (udp.LocalPort > 0)
{
udp.UdpClient = new UdpClient(udp.LocalPort);
}
else
{
udp.UdpClient = new UdpClient();
}
}
udp.UdpClient.Client.SendTimeout = udp.SendTimeout;
udp.UdpClient.Client.ReceiveTimeout = udp.ReceiveTimeout;
}
///
/// 断开(功能79)
///
/// UDP设备对象
public static void Disconnect(Udp udp)
{
Close(udp); // 复用 Close 逻辑
}
///
/// 连接(功能79)
///
/// UDP设备对象
/// 取消令牌
/// 连接结果
public static async Task Connect(Udp udp, CancellationToken ct = default)
{
// 与 ConnectAsync 功能相同,可以复用
return await ConnectAsync(udp, ct);
}
// ————————————————————————
// 功能 80
// ————————————————————————
///
/// 发送字符串(功能80)
///
/// UDP设备对象
/// 要发送的字符串
/// 取消令牌
public static async Task SendString(Udp udp, string str, CancellationToken ct = default)
{
await SendAsync(udp, str, ct); // 复用 SendAsync 逻辑
}
///
/// 发送字节(功能80)
///
/// UDP设备对象
/// 要发送的字节数组
/// 取消令牌
public static async Task SendByte(Udp udp, byte[] bytes, CancellationToken ct = default)
{
await SendAsync(udp, bytes, ct); // 复用 SendAsync 逻辑
}
///
/// 接收字节(功能80)
///
/// UDP设备对象
/// 取消令牌
/// 接收到的字节数组
public static async Task ReceiveByte(Udp udp, CancellationToken ct = default)
{
// UDP 接收通常不需要预先分配固定大小的 buffer,直接返回整个数据报
if (udp.UdpClient == null) throw new InvalidOperationException("UDP Client 未初始化。");
var timeoutMs = udp.ReceiveTimeout;
if (timeoutMs <= 0)
{
var res = await udp.UdpClient.ReceiveAsync();
return res.Buffer;
}
var readTask = udp.UdpClient.ReceiveAsync();
var timeoutTask = Task.Delay(timeoutMs, ct);
var completedTask = await Task.WhenAny(readTask, timeoutTask);
if (completedTask == timeoutTask)
{
throw new TimeoutException($"UDP通讯异常:读取操作在 {timeoutMs} ms内未完成");
}
var result = await readTask;
return result.Buffer;
}
///
/// 接收字符串(功能80)
///
/// UDP设备对象
/// 取消令牌
/// 接收到的字符串
public static async Task ReceiveString(Udp udp, CancellationToken ct = default)
{
var bytes = await ReceiveByte(udp, ct);
return Encoding.UTF8.GetString(bytes);
}
// ————————————————————————
// 内部辅助方法 (与 Tcp 风格一致)
// ————————————————————————
///
/// 关闭UDP连接
///
/// UDP设备对象
private static void Close(Udp udp)
{
udp.UdpClient?.Close();
// udp.UdpClient?.Dispose(); // 通常 Close 就足够了
}
///
/// 发送字节数组到UDP设备 (内部核心方法)
///
/// UDP设备对象
/// 要发送的字节数组
/// 取消令牌
public static async Task SendAsync(Udp udp, byte[] bytes, CancellationToken ct = default)
{
if (udp.UdpClient == null) throw new InvalidOperationException("UDP Client 未初始化。");
var timeoutMs = udp.SendTimeout;
if (timeoutMs <= 0)
{
await udp.UdpClient.SendAsync(bytes, bytes.Length);
return;
}
var sendTask = udp.UdpClient.SendAsync(bytes, bytes.Length);
var timeoutTask = Task.Delay(timeoutMs, ct);
var completedTask = await Task.WhenAny(sendTask, timeoutTask);
if (completedTask == timeoutTask)
{
throw new TimeoutException($"UDP通讯异常:写入操作在 {timeoutMs} ms内未完成");
}
await sendTask;
}
///
/// 发送字符串到UDP设备 (内部核心方法)
///
/// UDP设备对象
/// 要发送的字符串
/// 取消令牌
private static async Task SendAsync(Udp udp, string str, CancellationToken ct = default)
{
await SendAsync(udp, Encoding.UTF8.GetBytes(str), ct);
}
// ————————————————————————
// 实例方法 (可选,便于链式调用)
// ————————————————————————
///
/// 连接UDP设备(实例方法)
///
/// 取消令牌
/// 连接结果
public async Task ConnectAsync(CancellationToken ct = default)
{
return await ConnectAsync(this, ct);
}
}
}