20211010_CZPM_upperpc/网口升级/垂直剖面面浮标网口升级/Form1.cs
2023-07-27 11:01:29 +08:00

742 lines
26 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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();
}
}
}
}