421 lines
14 KiB
C#
421 lines
14 KiB
C#
using System;
|
||
using System.Drawing;
|
||
using System.Net.Sockets;
|
||
using System.Net;
|
||
using System.Text;
|
||
using System.Threading;
|
||
using System.Windows.Forms;
|
||
using System.Linq;
|
||
using System.Diagnostics;
|
||
using Sunny.UI;
|
||
|
||
namespace SLC1_N
|
||
{
|
||
public partial class Form_NetworkSet : Form
|
||
{
|
||
public Form_NetworkSet()
|
||
{
|
||
InitializeComponent();
|
||
}
|
||
|
||
private void ConfigTCP_Load(object sender, EventArgs e)
|
||
{
|
||
|
||
|
||
ch1ipaddress = Form1.f1.LL28CH1client.IP;
|
||
ch2ipaddress = Form1.f1.LL28CH2client.IP;
|
||
|
||
ReadConn.Interval = 500; // 连接状态定时器
|
||
ReadConn.Start();
|
||
}
|
||
|
||
// 连接状态定时器
|
||
private void ReadConn_Tick(object sender, EventArgs e)
|
||
{
|
||
// CH1
|
||
if (Form1.f1.LL28CH1client != null && Form1.f1.LL28CH1client.isRunning)
|
||
{
|
||
lb_CH1Communication_status.Text = "OK";
|
||
lb_CH1Communication_status.ForeColor = Color.Green;
|
||
}
|
||
else
|
||
{
|
||
lb_CH1Communication_status.Text = "NG";
|
||
lb_CH1Communication_status.ForeColor = Color.Red;
|
||
}
|
||
lb_CH1IP.Text = ch1ipaddress;
|
||
|
||
// CH2
|
||
if (Form1.f1.LL28CH2client != null && Form1.f1.LL28CH2client.isRunning)
|
||
{
|
||
lb_CH2Communication_status.Text = "OK";
|
||
lb_CH2Communication_status.ForeColor = Color.Green;
|
||
}
|
||
else
|
||
{
|
||
lb_CH2Communication_status.Text = "NG";
|
||
lb_CH2Communication_status.ForeColor = Color.Red;
|
||
}
|
||
lb_CH2IP.Text = ch2ipaddress;
|
||
|
||
// CH3
|
||
if (Form1.f1.LL28CH3client != null && Form1.f1.LL28CH3client.isRunning)
|
||
{
|
||
lb_CH3Communication_status.Text = "OK";
|
||
lb_CH3Communication_status.ForeColor = Color.Green;
|
||
}
|
||
else
|
||
{
|
||
lb_CH3Communication_status.Text = "NG";
|
||
lb_CH3Communication_status.ForeColor = Color.Red;
|
||
}
|
||
lb_CH3IP.Text = ch3ipaddress;
|
||
|
||
// CH4
|
||
if (Form1.f1.LL28CH4client != null && Form1.f1.LL28CH4client.isRunning)
|
||
{
|
||
lb_CH4Communication_status.Text = "OK";
|
||
lb_CH4Communication_status.ForeColor = Color.Green;
|
||
}
|
||
else
|
||
{
|
||
lb_CH4Communication_status.Text = "NG";
|
||
lb_CH4Communication_status.ForeColor = Color.Red;
|
||
}
|
||
lb_CH4IP.Text = ch4ipaddress;
|
||
|
||
lb_ComputerIP.Text = Form1.f1.localipaddress;
|
||
}
|
||
|
||
// CH1重连按钮
|
||
private void CH1TCPReCon_Click(object sender, EventArgs e)
|
||
{
|
||
bt_CH1TCPReconnect.Enabled = false;
|
||
Form1.f1.LL28CH1client?.Stop(); // 先停止线程(如果正在运行)
|
||
Form1.f1.LL28CH1client?.Disconnect(); // 断开旧连接
|
||
Form1.f1.LL28CH1client?.Connect(lb_CH1IP.Text); // 连接新 IP
|
||
Form1.f1.LL28CH1client?.Start(); // 重新启动线程
|
||
|
||
// 本地保存
|
||
var jsconfig = new JsonConfig("config.json");
|
||
jsconfig.SetValue("ch1ipaddress", lb_CH1IP.Text);
|
||
bt_CH1TCPReconnect.Enabled = true;
|
||
|
||
// 同步
|
||
Form1.f1.ch1ipaddress = lb_CH1IP.Text;
|
||
}
|
||
|
||
// CH1断开连接
|
||
private void CH1TCPBreak_Click(object sender, EventArgs e)
|
||
{
|
||
Form1.f1.LL28CH1client?.Disconnect(); // 断开旧连接
|
||
}
|
||
|
||
// CH2重连按钮
|
||
private void CH2TCPReCon_Click(object sender, EventArgs e)
|
||
{
|
||
Form1.f1.LL28CH2client?.Stop(); // 先停止线程(如果正在运行)
|
||
Form1.f1.LL28CH2client?.Disconnect(); // 断开旧连接
|
||
Form1.f1.LL28CH2client?.Connect(lb_CH2IP.Text); // 连接新 IP
|
||
Form1.f1.LL28CH2client?.Start(); // 重新启动线程
|
||
|
||
// 本地保存
|
||
var jsconfig = new JsonConfig("config.json");
|
||
jsconfig.SetValue("ch2ipaddress", lb_CH2IP.Text);
|
||
|
||
// 同步
|
||
Form1.f1.ch2ipaddress = lb_CH2IP.Text;
|
||
}
|
||
|
||
// CH2断开连接
|
||
private void CH2TCPBreak_Click(object sender, EventArgs e)
|
||
{
|
||
Form1.f1.LL28CH2client?.Disconnect(); // 断开旧连接
|
||
}
|
||
|
||
// CH3重连按钮
|
||
private void bt_CH3TCPReconnect_Click(object sender, EventArgs e)
|
||
{
|
||
Form1.f1.LL28CH3client?.Stop(); // 先停止线程(如果正在运行)
|
||
Form1.f1.LL28CH3client?.Disconnect(); // 断开旧连接
|
||
Form1.f1.LL28CH3client?.Connect(lb_CH3IP.Text); // 连接新 IP
|
||
Form1.f1.LL28CH3client?.Start(); // 重新启动线程
|
||
|
||
// 本地保存
|
||
var jsconfig = new JsonConfig("config.json");
|
||
jsconfig.SetValue("ch3ipaddress", lb_CH3IP.Text);
|
||
|
||
// 同步
|
||
Form1.f1.ch3ipaddress = lb_CH3IP.Text;
|
||
}
|
||
|
||
// CH3断开连接
|
||
private void CH3TCPBreak_Click(object sender, EventArgs e)
|
||
{
|
||
Form1.f1.LL28CH3client?.Disconnect(); // 断开旧连接
|
||
}
|
||
|
||
// CH4重连按钮
|
||
private void bt_CH4TCPReconnect_Click(object sender, EventArgs e)
|
||
{
|
||
Form1.f1.LL28CH4client?.Stop(); // 先停止线程(如果正在运行)
|
||
Form1.f1.LL28CH4client?.Disconnect(); // 断开旧连接
|
||
Form1.f1.LL28CH4client?.Connect(lb_CH4IP.Text); // 连接新 IP
|
||
Form1.f1.LL28CH4client?.Start(); // 重新启动线程
|
||
|
||
// 本地保存
|
||
var jsconfig = new JsonConfig("config.json");
|
||
jsconfig.SetValue("ch4ipaddress", lb_CH4IP.Text);
|
||
|
||
// 同步
|
||
Form1.f1.ch4ipaddress = lb_CH4IP.Text;
|
||
}
|
||
|
||
// CH4断开连接
|
||
private void CH4TCPBreak_Click(object sender, EventArgs e)
|
||
{
|
||
Form1.f1.LL28CH4client?.Disconnect(); // 断开旧连接
|
||
}
|
||
|
||
// 搜索IP按钮
|
||
private void UDPReadIP_Click(object sender, EventArgs e)
|
||
{
|
||
bt_UDPReadIP.Enabled = false;
|
||
try
|
||
{
|
||
UDPBroadcast();
|
||
}
|
||
finally
|
||
{
|
||
bt_UDPReadIP.Enabled = true;
|
||
}
|
||
}
|
||
|
||
string ch1ipaddress = null; // 通道1的IP地址
|
||
string ch2ipaddress = null; // 通道2的IP地址
|
||
string ch3ipaddress = null; // 通道1的IP地址
|
||
string ch4ipaddress = null; // 通道2的IP地址
|
||
string UDP_recvdata = ""; // 存储接收到的UDP数据
|
||
Socket udpsock; // UDP套接字
|
||
Thread UDPlisten;
|
||
|
||
private bool isUDPRunning = false; // UDP运行标志位
|
||
|
||
// 执行UDP广播搜索IP地址
|
||
private void UDPBroadcast()
|
||
{
|
||
try
|
||
{
|
||
if (isUDPRunning && udpsock != null)
|
||
{
|
||
Console.WriteLine("UDP广播已在运行中,直接发送广播消息...");
|
||
|
||
// 发送广播消息
|
||
byte[] sdata = Encoding.ASCII.GetBytes("hello,udp server");
|
||
|
||
string localIP = GetLocalIP();
|
||
if (localIP.Length > 1)
|
||
{
|
||
int lastIndex = localIP.LastIndexOf(".");
|
||
string broadcastip = localIP.Remove(lastIndex + 1) + "255";
|
||
IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Parse(broadcastip), 9999);
|
||
|
||
udpsock.SendTo(sdata, ipEndPoint);
|
||
}
|
||
return;
|
||
}
|
||
|
||
isUDPRunning = true;
|
||
ch1ipaddress = null;
|
||
ch2ipaddress = null;
|
||
ch3ipaddress = null;
|
||
ch4ipaddress = null;
|
||
|
||
UDP_recvdata = "";
|
||
|
||
if (udpsock != null) // 关闭旧的
|
||
{
|
||
udpsock.Close();
|
||
udpsock = null;
|
||
}
|
||
|
||
string PrefixIP = GetLocalIP(); // 获取本机IP
|
||
if (PrefixIP.Length <= 1) return;
|
||
|
||
// 设置广播地址
|
||
int lastDotIndex = PrefixIP.LastIndexOf(".");
|
||
string broadcastIP = PrefixIP.Remove(lastDotIndex + 1) + "255";
|
||
|
||
// 初始化UDP套接字
|
||
udpsock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
|
||
|
||
udpsock.Bind(new IPEndPoint(IPAddress.Any, 0)); // 0 表示由系统分配空闲端口
|
||
|
||
IPEndPoint broadcastEndPoint = new IPEndPoint(IPAddress.Parse(broadcastIP), 9999);
|
||
udpsock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1); // 启用套接字的广播功能
|
||
|
||
UDPlisten = new Thread(Thread_UDPListen); // 启动监听线程
|
||
UDPlisten.IsBackground = true;
|
||
UDPlisten.Start();
|
||
|
||
// 发送广播消息
|
||
byte[] data = Encoding.ASCII.GetBytes("hello,udp server");
|
||
udpsock.SendTo(data, broadcastEndPoint);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"UDPBroadcast()异常: {ex.Message}");
|
||
mxlLog.Instance.Error($"UDPBroadcast()异常,行号{ex.StackTrace} ", ex);
|
||
}
|
||
}
|
||
|
||
// 获取本机IP地址前缀(192.168.1.x)
|
||
public string GetLocalIP()
|
||
{
|
||
IPAddress[] ipArray = Dns.GetHostAddresses(Dns.GetHostName());
|
||
|
||
foreach (var ip in ipArray)
|
||
{
|
||
if (IsIPInRange(ip.ToString(), "192.168.1.0", "192.168.1.255"))
|
||
{
|
||
return ip.ToString();
|
||
}
|
||
}
|
||
|
||
// 如果没有找到192.168.1.x的IP,返回第一个IPv4地址
|
||
return ipArray.First(ip => ip.AddressFamily == AddressFamily.InterNetwork).ToString();
|
||
}
|
||
|
||
// 检查IP地址是否在指定范围内
|
||
public bool IsIPInRange(string input, string rangeStart, string rangeEnd)
|
||
{
|
||
uint ipValue = IPToUInt(input);
|
||
return ipValue >= IPToUInt(rangeStart) && ipValue <= IPToUInt(rangeEnd);
|
||
}
|
||
|
||
// 将IP地址转换为无符号整数用于比较
|
||
private uint IPToUInt(string ipAddress)
|
||
{
|
||
if (!IPAddress.TryParse(ipAddress, out var ip))
|
||
{
|
||
return 0;
|
||
}
|
||
|
||
byte[] bytes = ip.GetAddressBytes();
|
||
if (BitConverter.IsLittleEndian)
|
||
{
|
||
Array.Reverse(bytes);
|
||
}
|
||
|
||
return BitConverter.ToUInt32(bytes, 0);
|
||
}
|
||
|
||
// UDP监听线程:持续接收响应数据
|
||
private void Thread_UDPListen()
|
||
{
|
||
try
|
||
{
|
||
// 设置接收超时
|
||
udpsock.ReceiveTimeout = 1000; // 1秒超时
|
||
|
||
while (isUDPRunning && udpsock != null && udpsock.IsBound)
|
||
{
|
||
try
|
||
{
|
||
byte[] data = new byte[1024];
|
||
int rbytes = udpsock.Receive(data); // 244
|
||
string rdata = Encoding.ASCII.GetString(data, 0, rbytes);
|
||
Console.WriteLine($"UDP监听线程rdata: {rdata}");
|
||
|
||
UDP_recvdata += rdata + "\n";
|
||
ParseUDPdata(); // 解析接收到的数据
|
||
}
|
||
catch (SocketException ex) when (ex.SocketErrorCode == SocketError.TimedOut)
|
||
{
|
||
continue; // 超时是正常滴,继续循环
|
||
}
|
||
catch (SocketException ex) when (ex.SocketErrorCode == SocketError.Interrupted)
|
||
{
|
||
Console.WriteLine("UDP接收被正常中断");
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
mxlLog.Instance.Error($"UDP监听线程异常,行号{ex.StackTrace} ", ex);
|
||
}
|
||
finally
|
||
{
|
||
isUDPRunning = false;
|
||
}
|
||
}
|
||
|
||
/* 解析UDP响应数据,提取通道、IP地址
|
||
* 数据格式示例:
|
||
* 1:192.168.1.10 \n
|
||
* 2:192.168.1.11
|
||
*/
|
||
public void ParseUDPdata()
|
||
{
|
||
try
|
||
{
|
||
if (string.IsNullOrEmpty(UDP_recvdata)) return;
|
||
|
||
Console.WriteLine($"UDP_recvdata: {UDP_recvdata}");
|
||
ch1ipaddress = null;
|
||
ch2ipaddress = null;
|
||
ch3ipaddress = null;
|
||
ch4ipaddress = null;
|
||
|
||
string[] iparr = UDP_recvdata.Split('\n');
|
||
|
||
foreach (string ipdata in iparr)
|
||
{
|
||
if (string.IsNullOrEmpty(ipdata)) continue;
|
||
|
||
string[] chorip = ipdata.Split(':');
|
||
if (chorip.Length != 2) continue;
|
||
|
||
int ch = Convert.ToInt32(chorip[0]);
|
||
string ip = chorip[1];
|
||
|
||
switch (ch)
|
||
{
|
||
case 1: ch1ipaddress = ip; break;
|
||
case 2: ch2ipaddress = ip; break;
|
||
case 3: ch3ipaddress = ip; break;
|
||
case 4: ch4ipaddress = ip; break;
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
// 错误处理代码...
|
||
mxlLog.Instance.Error($"ParseUDPdata()异常,行号{ex.StackTrace} ", ex);
|
||
}
|
||
}
|
||
|
||
// 窗口关闭
|
||
private void ConfigTCP_FormClosing(object sender, FormClosingEventArgs e)
|
||
{
|
||
StopUDP();
|
||
//UDPlisten?.Join(500);
|
||
}
|
||
|
||
// 停止UDP
|
||
public void StopUDP()
|
||
{
|
||
isUDPRunning = false;
|
||
if (udpsock != null)
|
||
{
|
||
udpsock.Close();
|
||
udpsock = null;
|
||
}
|
||
}
|
||
|
||
|
||
/**/
|
||
}
|
||
}
|