Files
2026-06-08 17:06:10 +08:00

813 lines
25 KiB
C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO.Ports;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace DK_DC_Tool
{
public enum RETURN_ERR_STATE
{
RETURN_EOK = 0,
RETURN_ERR = -1,
RETURN_ESTOP = -2,
RETURN_ECONNECT = -3,
RETURN_ETIMEOUT = -4,
RETURN_EDECOMPOSE = -5
}
public partial class Form1 : Form
{
readonly string[] dev_type_tab = new string[] { "串口", "TCP" };
readonly string[] serial_baud_tab = new string[] { "1200", "2400", "4800", "9600", "19200", "38400", "57600", "115200" };
readonly string[] serial_databit_tab = new string[] { "5", "6", "7", "8" };
readonly string[] serial_stopbit_tab = new string[] { "1", "1.5", "2" };
readonly string[] serial_checksum_tab = new string[] { "无", "奇校验", "偶校验", "置1", "置0" };
readonly string[] protocol_op_tab = new string[] { "R", "W" };
enum DevType { DEV_TYPE_SERIAL = 0, DEV_TYPE_TCP };
int _dev_type;
byte _serial_addr = 0;
byte _serial_protocol = 0;
SerialPort _serial = null;
TcpClient _client = null;
Thread _parse_tid = null;
bool _isconnected = false;
bool _is_run = false;
bool _is_show_packet = true;
bool _is_reconnect = true;
bool _first_connect = true;
UInt32 _reconnect_cnt = 0;
Mutex _hw_mtx = null;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
cbxDevType.Items.AddRange(dev_type_tab);
cbxDevType.SelectedIndex = 0;
_dev_type = (int)DevType.DEV_TYPE_SERIAL;
gbxSerial.Visible = true;
gbxSerial.BringToFront();
gbxTcp.Visible = false;
string[] ports = SerialPort.GetPortNames();
cbxSerial.Items.AddRange(ports);
cbxSerial.SelectedIndex = cbxSerial.Items.Count > 0 ? 0 : -1;
cbxSerialBaud.Items.AddRange(serial_baud_tab);
cbxSerialBaud.SelectedIndex = 7;
cbxSerialDataBit.Items.AddRange(serial_databit_tab);
cbxSerialDataBit.SelectedIndex = 3;
cbxSerialStopBit.Items.AddRange(serial_stopbit_tab);
cbxSerialStopBit.SelectedIndex = 0;
cbxSerialCheckSum.Items.AddRange(serial_checksum_tab);
cbxSerialCheckSum.SelectedIndex = 0;
tbxSerialAddr.Text = "1";
tbxSerialProtocol.Text = "1";
//tbxTcpDestIP.Text = "192.168.2.32";
tbxTcpDestIP.Text = "192.168.3.31";
tbxTcpDestPort.Text = "5000";
gbxProtocol.Enabled = false;
cbxProtocolOp.Items.AddRange(protocol_op_tab);
cbxProtocolOp.SelectedIndex = 0;
_hw_mtx = new Mutex();
_parse_tid = new Thread(new ThreadStart(parse_entry));
_parse_tid.Name = "data_parse";
_parse_tid.IsBackground = true;
_parse_tid.Start();
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
try
{
if (_parse_tid != null)
_parse_tid.Abort();
}
finally
{
_parse_tid = null;
}
try
{
if (_serial != null)
_serial.Close();
}
finally
{
_serial = null;
}
try
{
if (_client != null)
_client.Close();
}
finally
{
_client = null;
}
Environment.Exit(0);
}
private void btnOpen_Click(object sender, EventArgs e)
{
if (btnOpen.Text == "打开")
{
if (cbxDevType.SelectedIndex == 0)
_dev_type = (int)DevType.DEV_TYPE_SERIAL;
else
_dev_type = (int)DevType.DEV_TYPE_TCP;
if (_dev_type == (int)DevType.DEV_TYPE_SERIAL)
{
try
{
_serial_addr = byte.Parse(tbxSerialAddr.Text);
_serial_protocol = byte.Parse(tbxSerialProtocol.Text);
}
catch
{
MessageBox.Show("串口地址和协议类型配置出错");
return;
}
}
//_log.Info("\r\n\r\n\r\n");
//_log.Info("启动");
btnOpen.Text = "关闭";
cbxDevType.Enabled = false;
gbxTcp.Enabled = false;
gbxSerial.Enabled = false;
gbxProtocol.Enabled = true;
_is_run = true;
if (_dev_type == (int)DevType.DEV_TYPE_SERIAL)
_is_reconnect = false;
else
_is_reconnect = true;
_first_connect = true;
_reconnect_cnt = 0;
}
else
{
//_log.Info("\r\n\r\n\r\n");
//_log.Info("结束");
btnOpen.Text = "打开";
cbxDevType.Enabled = true;
gbxTcp.Enabled = true;
gbxSerial.Enabled = true;
gbxProtocol.Enabled = false;
_is_run = false;
}
}
private void btnClear_Click(object sender, EventArgs e)
{
tbxProtocolDebug.Clear();
}
private void cbxDevType_SelectedIndexChanged(object sender, EventArgs e)
{
if (cbxDevType.SelectedIndex == 0)
{
gbxSerial.Visible = true;
gbxSerial.BringToFront();
gbxTcp.Visible = false;
}
else
{
gbxTcp.Visible = true;
gbxTcp.BringToFront();
gbxSerial.Visible = false;
}
}
private void cbxSerial_DropDown(object sender, EventArgs e)
{
string[] ports = SerialPort.GetPortNames();
cbxSerial.Items.Clear();
cbxSerial.Items.AddRange(ports);
cbxSerial.SelectedIndex = cbxSerial.Items.Count > 0 ? 0 : -1;
}
//代理
private delegate void change_tbx_delegate(string str);
private void tbxProtocolDebug_show(string str)
{
if (tbxProtocolDebug.InvokeRequired)
{
change_tbx_delegate cd = new change_tbx_delegate(tbxProtocolDebug_show);
tbxProtocolDebug.Invoke(cd, new object[] { str });
}
else
{
tbxProtocolDebug.Text += str;
tbxProtocolDebug.Text += "\r\n\r\n";
tbxProtocolDebug.Select(tbxProtocolDebug.TextLength, 0);
tbxProtocolDebug.ScrollToCaret();
}
}
private string bytes_to_hex_string(byte[] buf, int offset, int len)
{
string str = "";
for (int i = 0; i < len; i++)
{
str += buf[offset + i].ToString("X2") + " ";
}
return str;
}
private string bytes_to_string(byte[] buf, int offset, int len)
{
string str = "";
for (int i = 0; i < len; i++)
{
if ((buf[offset + i] < 32) || (buf[offset + i] > 126))
str += " .";
else
str += " " + ((char)buf[offset + i]).ToString();
str += " ";
}
return str;
}
private bool serial_open(ref SerialPort port, ComboBox serialNo, ComboBox serialBaud, ComboBox serialDataBit, ComboBox serialStopBit, ComboBox serialCheckSum)
{
if (!_is_run)
return false;
try
{
if (port != null)
port.Close();
port = null;
port = new SerialPort();
port.PortName = serialNo.Text;
port.BaudRate = int.Parse(serial_baud_tab[serialBaud.SelectedIndex]);
port.DataBits = int.Parse(serial_databit_tab[serialDataBit.SelectedIndex]);
switch (serialStopBit.SelectedIndex)
{
case 0:
port.StopBits = StopBits.One;
break;
case 1:
port.StopBits = StopBits.OnePointFive;
break;
case 2:
port.StopBits = StopBits.Two;
break;
default:
port.StopBits = StopBits.One;
break;
}
switch (serialCheckSum.SelectedIndex)
{
case 0:
port.Parity = Parity.None;
break;
case 1:
port.Parity = Parity.Odd;
break;
case 2:
port.Parity = Parity.Even;
break;
case 3:
port.Parity = Parity.Mark;
break;
case 4:
port.Parity = Parity.Space;
break;
default:
port.Parity = Parity.None;
break;
}
port.Handshake = Handshake.None;
port.Open();
}
catch
{
port = null;
return false;
}
return true;
}
private int serial_receive(SerialPort port, byte[] buffer, int offset, int max_len)
{
if (!_is_run)
return (int)RETURN_ERR_STATE.RETURN_ESTOP;
if (!_isconnected)
return (int)RETURN_ERR_STATE.RETURN_ECONNECT;
if (port == null)
return (int)RETURN_ERR_STATE.RETURN_ERR;
if (port.IsOpen == false)
return (int)RETURN_ERR_STATE.RETURN_ERR;
int len = 0;
int rc = 0;
while (max_len > 0)
{
Thread.Sleep(35);
if (!_is_run)
{
rc = (int)RETURN_ERR_STATE.RETURN_ESTOP;
break;
}
if (!_isconnected)
{
rc = (int)RETURN_ERR_STATE.RETURN_ECONNECT;
break;
}
try
{
if (port.BytesToRead < 0)
{
rc = (int)RETURN_ERR_STATE.RETURN_ERR;
break;
}
if (port.BytesToRead == 0)
break;
rc = port.Read(buffer, offset + len, max_len);
if (rc <= 0)
{
rc = (int)RETURN_ERR_STATE.RETURN_ERR;
break;
}
len += rc;
max_len -= rc;
}
catch
{
rc = (int)RETURN_ERR_STATE.RETURN_ERR;
break;
}
}
if (rc >= 0)
rc = len;
return rc;
}
private int serial_send(SerialPort port, byte[] buffer)
{
if (!_is_run)
return (int)RETURN_ERR_STATE.RETURN_ESTOP;
if (!_isconnected)
return (int)RETURN_ERR_STATE.RETURN_ECONNECT;
if (port == null)
return (int)RETURN_ERR_STATE.RETURN_ERR;
if (port.IsOpen == false)
return (int)RETURN_ERR_STATE.RETURN_ERR;
try
{
port.Write(buffer, 0, buffer.Length);
}
catch
{
return (int)RETURN_ERR_STATE.RETURN_ERR;
}
return buffer.Length;
}
private bool tcp_connect(ref TcpClient client, string ip, string port)
{
if (!_is_run)
return false;
try
{
if (client != null)
client.Close();
client = null;
client = new TcpClient();
if (!client.ConnectAsync(ip, int.Parse(port)).Wait(2000))
{
client.Close();
client = null;
return false;
}
}
catch
{
client = null;
return false;
}
return true;
}
private int tcp_receive(TcpClient client, byte[] buffer, int offset, int max_len)
{
if (!_is_run)
return (int)RETURN_ERR_STATE.RETURN_ESTOP;
if (!_isconnected)
return (int)RETURN_ERR_STATE.RETURN_ECONNECT;
if (client == null)
return (int)RETURN_ERR_STATE.RETURN_ERR;
if (client.Connected == false)
return (int)RETURN_ERR_STATE.RETURN_ERR;
NetworkStream networkStream = null;
try
{
networkStream = client.GetStream();
}
catch
{
return (int)RETURN_ERR_STATE.RETURN_ERR;
}
int len = 0;
int rc = 0;
while (max_len > 0)
{
Thread.Sleep(20);
if (!_is_run)
{
rc = (int)RETURN_ERR_STATE.RETURN_ESTOP;
break;
}
if (!_isconnected)
{
rc = (int)RETURN_ERR_STATE.RETURN_ECONNECT;
break;
}
try
{
if (networkStream.DataAvailable == false)
break;
rc = networkStream.Read(buffer, offset + len, max_len);
if (rc <= 0)
{
rc = (int)RETURN_ERR_STATE.RETURN_ERR;
break;
}
len += rc;
max_len -= rc;
}
catch
{
rc = (int)RETURN_ERR_STATE.RETURN_ERR;
break;
}
}
if (rc >= 0)
rc = len;
return rc;
}
private int tcp_send(TcpClient client, byte[] buffer)
{
if (!_is_run)
return (int)RETURN_ERR_STATE.RETURN_ESTOP;
if (!_isconnected)
return (int)RETURN_ERR_STATE.RETURN_ECONNECT;
if (client == null)
return (int)RETURN_ERR_STATE.RETURN_ERR;
if (client.Connected == false)
return (int)RETURN_ERR_STATE.RETURN_ERR;
try
{
NetworkStream networkStream = _client.GetStream();
networkStream.Write(buffer, 0, buffer.Length);
}
catch
{
return (int)RETURN_ERR_STATE.RETURN_ERR;
}
return buffer.Length;
}
private int hw_receive(byte[] buffer, int offset, int max_len)
{
int rc = 0;
if (_dev_type == (int)DevType.DEV_TYPE_SERIAL)
rc = serial_receive(_serial, buffer, offset, max_len);
else
rc = tcp_receive(_client, buffer, offset, max_len);
string str = null;
if(rc < 0)
{
if(rc != (int)RETURN_ERR_STATE.RETURN_ESTOP)
{
string err_str = "接收数据异常";
// _log.Warn(err_str);
str = "\r\n" + DateTime.Now.ToString() + '.' + DateTime.Now.Millisecond.ToString("d3") + "\r\n";
str += err_str + "\r\n";
}
}
else if (rc > 0)
{
//buffer = new byte[] { 0x02 ,0x00, 0x00, 0x00, 0xd9, 0x54, 0x30, 0x32, 0x30, 0x32, 0x30, 0x30, 0x30, 0x31, 0x30, 0x3d, 0x30, 0x2e, 0x32, 0x39, 0x37, 0x2c, 0x33, 0x32, 0x30, 0x38, 0x2e, 0x35, 0x36, 0x33, 0x2c, 0x31, 0x2e, 0x36, 0x35, 0x31, 0x3b, 0x30, 0x30, 0x30, 0x31, 0x31, 0x3d, 0x31, 0x3b, 0x30, 0x30, 0x30, 0x31, 0x32, 0x3d, 0x30, 0x3b, 0x30, 0x31, 0x30, 0x31, 0x30, 0x3d, 0x30, 0x2e, 0x30, 0x31, 0x33, 0x2c, 0x2d, 0x38, 0x39, 0x2e, 0x39, 0x35, 0x34, 0x2c, 0x30, 0x2e, 0x31, 0x37, 0x34, 0x3b, 0x30, 0x31, 0x30, 0x31, 0x31, 0x3d, 0x30, 0x3b, 0x30, 0x31, 0x30, 0x32, 0x30, 0x3d, 0x30, 0x2e, 0x30, 0x30, 0x38, 0x2c, 0x38, 0x39, 0x2e, 0x39, 0x35, 0x34, 0x2c, 0x30, 0x2e, 0x31, 0x30, 0x30, 0x3b, 0x30, 0x31, 0x30, 0x32, 0x31, 0x3d, 0x30, 0x3b, 0x30, 0x31, 0x30, 0x33, 0x30, 0x3d, 0x30, 0x2e, 0x30, 0x30, 0x36, 0x2c, 0x32, 0x37, 0x39, 0x39, 0x2e, 0x34, 0x37, 0x32, 0x2c, 0x30, 0x2e, 0x34, 0x30, 0x39, 0x3b, 0x30, 0x31, 0x30, 0x33, 0x31, 0x3d, 0x30, 0x3b, 0x30, 0x31, 0x30, 0x34, 0x30, 0x3d, 0x30, 0x2e, 0x30, 0x35, 0x39, 0x2c, 0x33, 0x30, 0x37, 0x2e, 0x36, 0x37, 0x38, 0x2c, 0x30, 0x2e, 0x32, 0x35, 0x36, 0x3b, 0x30, 0x31, 0x30, 0x34, 0x31, 0x3d, 0x30, 0x3b, 0x30, 0x31, 0x30, 0x35, 0x30, 0x3d, 0x30, 0x2e, 0x32, 0x39, 0x37, 0x2c, 0x31, 0x30, 0x2e, 0x33, 0x31, 0x33, 0x2c, 0x30, 0x2e, 0x34, 0x39, 0x32, 0x3b, 0x30, 0x31, 0x30, 0x35, 0x31, 0x3d, 0x30, 0x3b, 0x03 };
//rc = buffer.Length;
//_log.Debug("接收到数据");
string hex_str = "recv: " + bytes_to_hex_string(buffer, offset, rc);
string raw_str = " " + bytes_to_string(buffer, offset, rc);
//_log.Debug(hex_str);
//_log.Debug(raw_str);
if (_is_show_packet)
{
str = "\r\n" + DateTime.Now.ToString() + '.' + DateTime.Now.Millisecond.ToString("d3") + "\r\n";
str += hex_str + "\r\n" + raw_str + "\r\n";
}
}
if (str != null)
tbxProtocolDebug_show(str);
return rc;
}
private int hw_send(ToolPacket packet)
{
int rc = 0;
ToolPacket send_packet = null;
if (_dev_type == (int)DevType.DEV_TYPE_SERIAL)
{
ToolSerialPacket serial_packet = new ToolSerialPacket();
serial_packet.addr = _serial_addr;
serial_packet.protocol = _serial_protocol;
serial_packet.op = packet.op;
serial_packet.mid = packet.mid;
serial_packet.data_domain_str = packet.data_domain_str;
send_packet = serial_packet;
}
else
{
send_packet = packet;
}
byte[] buffer = send_packet.compose_protocol();
_hw_mtx.WaitOne();
if (_dev_type == (int)DevType.DEV_TYPE_SERIAL)
rc = serial_send(_serial, buffer);
else
rc = tcp_send(_client, buffer);
_hw_mtx.ReleaseMutex();
string str = null;
if (rc < 0)
{
if(rc != (int)RETURN_ERR_STATE.RETURN_ESTOP)
{
string err_str = "发送失败";
//_log.Warn(err_str);
str = "\r\n" + DateTime.Now.ToString() + '.' + DateTime.Now.Millisecond.ToString("d3") + "\r\n";
str += err_str + "\r\n";
}
}
else
{
//_log.Debug("发送数据");
string hex_str = "send: " + bytes_to_hex_string(buffer, 0, buffer.Length);
string raw_str = " " + bytes_to_string(buffer, 0, buffer.Length);
//_log.Debug(hex_str);
//_log.Debug(raw_str);
if (_is_show_packet)
{
str = "\r\n" + DateTime.Now.ToString() + '.' + DateTime.Now.Millisecond.ToString("d3") + "\r\n";
str += hex_str + "\r\n" + raw_str + "\r\n";
}
}
if(str != null)
tbxProtocolDebug_show(str);
return rc;
}
byte[] normal_buf = new byte[1024];
private void parse_entry()
{
Control.CheckForIllegalCrossThreadCalls = false;
while (true)
{
// 未使能运行时,关闭连接,等待使能
if(!_is_run)
{
try
{
if (_serial != null)
_serial.Close();
}
finally
{
_serial = null;
}
try
{
if (_client != null)
_client.Close();
}
finally
{
_client = null;
}
_isconnected = false;
_first_connect = true;
Thread.Sleep(50);
continue;
}
// 未连接时,连接硬件接口,失败 2s 周期重连
if(!_isconnected)
{
// 不使能重连
if(!_is_reconnect && !_first_connect)
{
try
{
if (_serial != null)
_serial.Close();
}
finally
{
_serial = null;
}
try
{
if (_client != null)
_client.Close();
}
finally
{
_client = null;
}
Thread.Sleep(50);
continue;
}
_first_connect = false;
_reconnect_cnt++;
if (_dev_type == (int)DevType.DEV_TYPE_SERIAL)
{
if (serial_open(ref _serial, cbxSerial, cbxSerialBaud, cbxSerialDataBit, cbxSerialStopBit, cbxSerialCheckSum))
{
tbxProtocolDebug_show("\r\n\r\n" + DateTime.Now.ToString() + '.' + DateTime.Now.Millisecond.ToString("d3") + "\r\n打开串口成功!\r\n");
//_log.Info("打开串口成功!");
_isconnected = true;
Thread.Sleep(50);
continue;
}
else
{
tbxProtocolDebug_show("\r\n\r\n" + DateTime.Now.ToString() + '.' + DateTime.Now.Millisecond.ToString("d3") + "\r\n打开串口失败!\r\n");
//_log.Warn("打开串口失败!");
}
}
else
{
if (tcp_connect(ref _client, tbxTcpDestIP.Text, tbxTcpDestPort.Text))
{
tbxProtocolDebug_show("\r\n\r\n" + DateTime.Now.ToString() + '.' + DateTime.Now.Millisecond.ToString("d3") + "\r\n网络连接成功!\r\n");
//_log.Info("网络连接成功!");
_isconnected = true;
Thread.Sleep(50);
continue;
}
else
{
tbxProtocolDebug_show("\r\n\r\n" + DateTime.Now.ToString() + '.' + DateTime.Now.Millisecond.ToString("d3") + "\r\n网络连接失败!\r\n");
//_log.Warn("网络连接失败!");
}
}
Thread.Sleep(2000);
continue;
}
int recv_len = hw_receive(normal_buf, 0, normal_buf.Length);
if (recv_len < 0)
{
Thread.Sleep(50);
_isconnected = false;
continue;
}
}
}
private void btnProtocolSend_Click(object sender, EventArgs e)
{
ToolPacket packet = new ToolPacket();
if (cbxProtocolOp.SelectedIndex == 0)
packet.op = 'R';
else
packet.op = 'W';
packet.mid = tbxProtocolMID.Text;
packet.data_domain_str = tbxProtocolData.Text;
hw_send(packet);
}
}
}