20211010_CZPM_upperpc/网口升级/垂直剖面面浮标网口升级/Form1.cs

742 lines
26 KiB
C#
Raw Permalink Normal View History

2023-07-27 03:01:29 +00:00
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
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.Forms;
namespace
{
public partial class Form1 : Form
{
bool C_S = true;
string _ip = "192.168.0.101";
string _ip_client = "192.168.0.57";
int _port = 8899;
Client _client = new Client();
public Form1()
{
InitializeComponent();
textBox1.Text = _ip;
textBox2.Text = _port.ToString();
groupBox2.Enabled = false;
comboBox1.Text = "客户端";
}
bool _server_con;
//客户端连接
private void button2_Click(object sender, EventArgs e)
{
if (button2.Text == (C_S ? "连接" : "打开服务器"))
{
if (C_S)
{
//连接Socket
_client.InitSocket(textBox1.Text, Convert.ToInt32(textBox2.Text));
bool isConnected = _client.Connect();
if (isConnected)
{
_client.pushSockets = ReceiveMess;//注册推送器
label5.Text = "已连接!";
groupBox2.Enabled = true;
button2.Text = "断开";
}
else
{
label5.Text = "连接失败!";
groupBox2.Enabled = false;
}
}
else
{
_server_con = OpenServer(Convert.ToInt32(textBox2.Text));
if (_server_con)
{
label5.Text = "已打开!";
groupBox2.Enabled = true;
button2.Text = "关闭服务器";
}
else
{
label5.Text = "打开失败!";
groupBox2.Enabled = false;
}
}
}
else if (button2.Text == (C_S ? "断开" : "关闭服务器"))
{
if (C_S)
{
_client.Stop();
label5.Text = "已断开!";
groupBox2.Enabled = false;
button2.Text = "连接";
}
else
{
CloseServer();
label5.Text = "已关闭!";
groupBox2.Enabled = false;
button2.Text = "打开服务器";
}
}
}
//客户端数据接收
private void ReceiveMess(Sockets sks)
{
if (sks.ex != null)
{
if (sks.ClientDispose == true)
{
//由于未知原因引发异常.导致客户端下线. 比如网络故障.或服务器断开连接.
//SetClientState(string.Format("客户端下线.!异常消息:{0}\r\n", sks.ex));
}
else
{
//SetClientState(string.Format("异常消息:{0}\r\n", sks.ex));
}
//timerConnect.Enabled = true;
}
else if (sks.Offset == 0)
{
//客户端主动下线
// SetClientState("客户端下线.!");
}
else
{
byte[] buffer = new byte[sks.Offset];
Array.Copy(sks.RecBuffer, buffer, sks.Offset);
string str = Encoding.UTF8.GetString(buffer);
try
{
ParsingData(new List<byte>(buffer));
}
catch (Exception)
{
return;
}
//if (sks.Client.Client.Available > 0)//判断消息是否发送完成socket的数据大小限制分多个包发送
//{
// Console.Write(str);
//}
//else
//{
//}
}
}
string _message = "";
byte[] bbh = new byte[4] { 0x00, 0x00, 0x00, 0x00 };
//解析
public void ParsingData(List<byte> byteList)
{
//帧头
byte[] _header = new byte[] { 0xEF, 0xFE, 0xFE, 0xEF };
//帧尾
byte _end = 0x16;
//长度校验
int _len = 0;
//校验
int _check = 0;
//功能码
byte _fun_code = 0;
//类型
byte _kind = 0;
//数据类型
byte _data_type = 0;
//校验当前List是否为空或者长度
if (byteList == null || byteList.Count == 0)
return;
//校验帧头
if (byteList[0] != _header[0] && byteList[0] != _header[2])
return;
if (byteList[1] != _header[1] && byteList[1] != _header[3])
return;
//校验帧尾
if (byteList[byteList.Count - 1] != _end)
return;
//获取检验长度
_len = Convert.ToInt32(byteList[2].ToString("X2") + byteList[3].ToString("X2"), 16);
//获取检验的校验和
for (int i = 0; i < byteList.Count - 2; i++)
{
_check += byteList[i];
}
_check = _check & 0xFF;
//长度 及 累加和校验
if (_len != byteList.Count - 4 || byteList[byteList.Count - 2] != _check)
return;
_len = 0;
_check = 0;
//功能码
_fun_code = byteList[5];
Console.WriteLine(_fun_code);
//类型
_kind = byteList[6];
switch (_fun_code)
{
//升级文件请求回复
case 0x6E:
switch (byteList[7])
{
case 0x00:
_message += "获取成功";
break;
case 0x01:
_message += "空";
break;
case 0x02:
_message += "设备忙";
break;
default:
break;
}
break;
//版本号查询回复
case 0x6F:
bbh[0] = byteList[7];
bbh[1] = byteList[8];
bbh[2] = byteList[9];
bbh[3] = byteList[10];
switch (byteList[11])
{
case 0x00:
_message += "获取成功";
break;
case 0x01:
_message += "空";
break;
case 0x02:
_message += "设备忙";
break;
default:
break;
}
Invoke((EventHandler)(delegate
{
textBox4.Text = ((int)bbh[0]).ToString() + "." + ((int)bbh[1]).ToString() + "." + ((int)bbh[2]).ToString() + "." + ((int)bbh[3]).ToString();
}));
break;
case 0x66:
int _start = Convert.ToInt32(byteList[6].ToString("X2") + byteList[7].ToString("X2") + byteList[8].ToString("X2") + byteList[9].ToString("X2"), 16);
int _Length = Convert.ToInt32(byteList[10].ToString("X2") + byteList[11].ToString("X2"), 16);
_send(_start, _Length);
break;
default:
break;
}
}
private void _send(int _start, int _Length)
{
List<byte> _send = new List<byte>();
//读取文件的实际长度
int _read_length = (binchar.Length - _start) >= _Length ? _Length : binchar.Length - _start;
byte[] _read = new byte[2];
if (_read_length > 255)
{
_read[0] = BitConverter.GetBytes(_read_length)[1];
_read[1] = BitConverter.GetBytes(_read_length)[0];
}
else
{
_read[0] = 0x00;
_read[1] = (byte)_read_length;
}
byte bb = (byte)((_start + _Length) >= binchar.Length ? 0xFF : 0x00);
_send.AddRange(new List<byte>() { 0xEF, 0xFE, BitConverter.GetBytes(_read_length + 12)[1], BitConverter.GetBytes(_read_length + 12)[0], 0x01, 0x66, 0x00, BitConverter.GetBytes(binchar.Length)[3], BitConverter.GetBytes(binchar.Length)[2], BitConverter.GetBytes(binchar.Length)[1], BitConverter.GetBytes(binchar.Length)[0], (byte)((_start + _Length) >= binchar.Length ? 0xFF : 0x00), _read[0], _read[1] });
for (int i = _start; i < _start + _read_length; i++)
{
_send.Add(binchar[i]);
}
int a = 0;
for (int i = 0; i < _send.Count; i++)
{
a += _send[i];
}
_send.AddRange(new List<byte>() { (byte)(a & 0xFF), 0x16 });
if (C_S)
{
_client.SendData(_send.ToArray());
}
else
{
send_server(_ip_client, _send.ToArray());
}
Console.WriteLine("回复成功" + System.DateTime.Now + "当前地址位" + _start + "当前长度" + _Length);
Invoke((EventHandler)(delegate
{
if (binchar.Length != 0)
{
label3.Text = "当前已上传" + (int)((double)(_start + _read_length) * 100 / (double)binchar.Length) + "%";
}
}));
}
private void button3_Click(object sender, EventArgs e)
{
OpenFileDialog dialog = new OpenFileDialog();
dialog.Multiselect = false;//不允许多选
dialog.Title = "请选择升级程序";//窗口title
dialog.Filter = "文本文件(*.bin)|*.*";//可选择的文件类型
if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
textBox3.Text = dialog.FileName; //获取文件路径
}
}
byte[] binchar = new byte[] { };
//文件发送
private void button1_Click(object sender, EventArgs e)
{
if (textBox3.Text == "" || !textBox3.Text.Contains(".bin"))
{
label3.Text = "请选择升级文件!!!";
return;
}
if (_client.IsOnline() || _server_con)
{
//读取文件
int file_len;//bin文件长度
int addr = 0;//
int count = 0;//换行计数
FileStream MyFile = new FileStream(textBox3.Text, FileMode.Open, FileAccess.Read);
BinaryReader Reader = new BinaryReader(MyFile);
file_len = (int)MyFile.Length;
StringBuilder str = new StringBuilder();
binchar = Reader.ReadBytes(file_len);
Reader.Close();
string md5 = MD5.Encrypt(binchar);
Console.WriteLine(md5);
byte[] _md5 = new byte[md5.Length / 2];
for (int i = 0; i < md5.Length; i += 2)
{
_md5[i / 2] = Convert.ToByte(md5.Substring(i, 2), 16);
}
byte[] _send = new byte[] { 0xFE, 0xEF, 0x00, 0x1D, 0x00, 0x6E, 0x00, bbh[0], bbh[1], bbh[2], bbh[3], 0x00, 0x00, 0x00, 0x00, _md5[0], _md5[1], _md5[2], _md5[3], _md5[4], _md5[5], _md5[6], _md5[7], _md5[8], _md5[9], _md5[10], _md5[11], _md5[12], _md5[13], _md5[14], _md5[15], 0x00, 0x16 };
int a = 0;
for (int i = 0; i < _send.Length - 2; i++)
{
a += _send[i];
}
a = a & 0xFF;
_send[31] = (byte)a;
if (C_S)
{
_client.SendData(_send);
}
else
{
send_server(_ip_client, _send);
}
}
else
{
button2_Click(null, null);
}
}
//版本查询
private void button4_Click(object sender, EventArgs e)
{
if (_client.IsOnline() || _server_con)
{
byte[] _send = new byte[] { 0xFE, 0xEF, 0x00, 0x05, 0x00, 0x6F, 0x00, 0x00, 0x16 };
int a = 0;
for (int i = 0; i < _send.Length - 2; i++)
{
a += _send[i];
}
a = a & 0xFF;
_send[7] = (byte)a;
if (C_S)
{
_client.SendData(_send);
}
else
{
send_server(_ip_client, _send);
}
}
else
{
button2_Click(null, null);
}
}
public static byte[] intToByte4(int Num)
{
byte[] abyte = new byte[8]; //int为32位除4位数组为8
int j = 0xf;
int z = 4; //转换的位数
for (int i = 0; i < 8; i++)
{
int y = j << z * i;
int x = Num & y;
x = x >> (z * i);
abyte[i] = (byte)(x);
}
return abyte;
}
private void comboBox1_TextChanged(object sender, EventArgs e)
{
if (comboBox1.Text == "客户端")
{
C_S = true;
button2.Text = "连接";
label7.Text = "目标IP地址";
label8.Text = "目标端口号";
}
else if (comboBox1.Text == "服务器")
{
C_S = false;
button2.Text = "打开服务器";
label7.Text = "本机IP";
label8.Text = "端口号";
textBox1.Text = GetLocalIP();
}
}
/***********************获取当前主机IP*******************************/
public static string GetLocalIP()
{
try
{
//获得当前主机名称
string HostName = Dns.GetHostName();
IPHostEntry IpEntry = Dns.GetHostEntry(HostName);
for (int i = 0; i < IpEntry.AddressList.Length; i++)
{
//从ip地址列表中筛选出IPv4类型的IP地址
//AddressFamily.InterNetWork表示此IP为IPv4
//AddressFamily.InterNetWorkV6表示此地址为IPv6类型
if (IpEntry.AddressList[i].AddressFamily == AddressFamily.InterNetwork)
{
return IpEntry.AddressList[i].ToString();
}
}
return "";
}
catch (Exception ex)
{
MessageBox.Show("获取本机IP出错:" + ex.Message);
return "";
}
}
/*************************************服务端*****************************************/
/******************服务端************************/
/**
//定义Socket对象
private static Socket serverSocket = null;
//定义监听线程
private static Thread listenThread;
//定义接受客户端数据线程
private static Thread threadReceive;
//定义双方通信
private static Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);**/
private static String str;
//服务端
private static Socket ServerSocket = null;
//tcp客户端字典
public static Dictionary<string, MySession> dic_ClientSocket = new Dictionary<string, MySession>();
//线程字典,每新增一个连接就添加一条线程
private static Dictionary<string, Thread> dic_ClientThread = new Dictionary<string, Thread>();
//监听客户端连接的标志
private static bool Flag_Listen = true;
/// <summary>
/// 启动服务
/// </summary>
/// <param name="port">端口号</param>
public bool OpenServer(int port)
{
try
{
Flag_Listen = true;
// 创建负责监听的套接字,注意其中的参数;
ServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// 创建包含ip和端口号的网络节点对象
IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, port);
try
{
// 将负责监听的套接字绑定到唯一的ip和端口上
ServerSocket.Bind(endPoint);
}
catch
{
return false;
}
// 设置监听队列的长度;
ServerSocket.Listen(100);
// 创建负责监听的线程;
Thread Thread_ServerListen = new Thread(ListenConnecting);
Thread_ServerListen.IsBackground = true;
Thread_ServerListen.Start();
return true;
}
catch
{
return false;
}
}
/// <summary>
/// 关闭服务
/// </summary>
public static void CloseServer()
{
lock (dic_ClientSocket)
{
foreach (var item in dic_ClientSocket)
{
item.Value.Close();//关闭每一个连接
}
dic_ClientSocket.Clear();//清除字典
}
lock (dic_ClientThread)
{
foreach (var item in dic_ClientThread)
{
item.Value.Abort();//停止线程
}
dic_ClientThread.Clear();
}
Flag_Listen = false;
//ServerSocket.Shutdown(SocketShutdown.Both);//服务端不能主动关闭连接,需要把监听到的连接逐个关闭
if (ServerSocket != null)
ServerSocket.Close();
}
/// <summary>
/// 监听客户端请求的方法;
/// </summary>
private void ListenConnecting()
{
while (Flag_Listen) // 持续不断的监听客户端的连接请求;
{
try
{
Socket sokConnection = ServerSocket.Accept(); // 一旦监听到一个客户端的请求,就返回一个与该客户端通信的 套接字;
// 将与客户端连接的 套接字 对象添加到集合中;
string str_EndPoint = sokConnection.RemoteEndPoint.ToString();
MySession myTcpClient = new MySession() { TcpSocket = sokConnection };
//创建线程接收数据
Thread th_ReceiveData = new Thread(ReceiveData);
th_ReceiveData.IsBackground = true;
th_ReceiveData.Start(myTcpClient);
//把线程及客户连接加入字典
foreach (string key in dic_ClientThread.Keys)
{
dic_ClientThread[key].Abort();
}
dic_ClientThread.Clear();
dic_ClientSocket.Clear();
dic_ClientThread.Add(str_EndPoint, th_ReceiveData);
dic_ClientSocket.Add(str_EndPoint.Split(':')[0], myTcpClient);
_ip_client = str_EndPoint.Split(':')[0];
Console.WriteLine(str_EndPoint);
}
catch (Exception err)
{
Console.WriteLine(err.Message);
}
Thread.Sleep(200);
}
}
/// <summary>
/// 接收数据
/// </summary>
/// <param name="sokConnectionparn"></param>
private void ReceiveData(object sokConnectionparn)
{
MySession tcpClient = sokConnectionparn as MySession;
Socket socketClient = tcpClient.TcpSocket;
bool Flag_Receive = true;
while (Flag_Receive)
{
try
{
// 定义一个2M的缓存区
byte[] arrMsgRec = new byte[1024 * 1024 * 2];
// 将接受到的数据存入到输入 arrMsgRec中
int length = -1;
try
{
length = socketClient.Receive(arrMsgRec); // 接收数据,并返回数据的长度;
}
catch (Exception err)
{
Console.WriteLine("断开连接时产生的信息:" + err.Message);
Flag_Receive = false;
// 从通信线程集合中删除被中断连接的通信线程对象;
foreach (string key in dic_ClientThread.Keys)
{
dic_ClientSocket.Remove(key);//删除客户端字典中该socket
if (dic_ClientThread[key].IsAlive)
{
dic_ClientThread[key].Abort();//关闭线程
}
dic_ClientThread.Remove(key);//删除字典中该线程
}
tcpClient = null;
socketClient = null;
CloseServer();//关闭服务器
OpenServer(8899);
break;
}
byte[] buf = new byte[length];
Array.Copy(arrMsgRec, buf, length);
lock (tcpClient.m_Buffer)
{
tcpClient.AddQueue(buf);
}
str = Encoding.Default.GetString(buf, 0, length);
//数据解析
//data_analysis(str);
ParsingData(new List<byte>(buf));
}
catch (Exception err)
{
Console.WriteLine(err.Message);
}
Thread.Sleep(100);
}
}
/// <summary>
/// 发送数据给指定的客户端
/// </summary>
/// <param name="_endPoint">客户端套接字</param>
/// <param name="_buf">发送的数组</param>
/// <returns></returns>
public static bool send_server(string _endPoint, byte[] buffer)
{
MySession myT = new MySession();
if (dic_ClientSocket.TryGetValue(_endPoint, out myT))
{
myT.Send(buffer);
return true;
}
else
{
return false;
}
}
public class MySession
{
public Socket TcpSocket;//socket对象
public List<byte> m_Buffer = new List<byte>();//数据缓存区
public MySession()
{
}
/// <summary>
/// 发送数据
/// </summary>
/// <param name="buf"></param>
public void Send(byte[] buf)
{
if (buf != null)
{
try
{
TcpSocket.Send(buf);
}
catch (Exception err)
{
Console.WriteLine("发送指令失败,当前设备未连接");
}
}
}
/// <summary>
/// 获取连接的ip
/// </summary>
/// <returns></returns>
public string GetIp()
{
IPEndPoint clientipe = (IPEndPoint)TcpSocket.RemoteEndPoint;
string _ip = clientipe.Address.ToString();
return _ip;
}
/// <summary>
/// 关闭连接
/// </summary>
public void Close()
{
TcpSocket.Shutdown(SocketShutdown.Both);
}
/// <summary>
/// 提取正确数据包
/// </summary>
public byte[] GetBuffer(int startIndex, int size)
{
byte[] buf = new byte[size];
m_Buffer.CopyTo(startIndex, buf, 0, size);
m_Buffer.RemoveRange(0, startIndex + size);
return buf;
}
/// <summary>
/// 添加队列数据
/// </summary>
/// <param name="buffer"></param>
public void AddQueue(byte[] buffer)
{
m_Buffer.AddRange(buffer);
}
/// <summary>
/// 清除缓存
/// </summary>
public void ClearQueue()
{
m_Buffer.Clear();
}
}
}
}