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(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 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 _send = new List(); //读取文件的实际长度 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() { 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)(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 dic_ClientSocket = new Dictionary(); //线程字典,每新增一个连接就添加一条线程 private static Dictionary dic_ClientThread = new Dictionary(); //监听客户端连接的标志 private static bool Flag_Listen = true; /// /// 启动服务 /// /// 端口号 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; } } /// /// 关闭服务 /// 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(); } /// /// 监听客户端请求的方法; /// 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); } } /// /// 接收数据 /// /// 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(buf)); } catch (Exception err) { Console.WriteLine(err.Message); } Thread.Sleep(100); } } /// /// 发送数据给指定的客户端 /// /// 客户端套接字 /// 发送的数组 /// 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 m_Buffer = new List();//数据缓存区 public MySession() { } /// /// 发送数据 /// /// public void Send(byte[] buf) { if (buf != null) { try { TcpSocket.Send(buf); } catch (Exception err) { Console.WriteLine("发送指令失败,当前设备未连接"); } } } /// /// 获取连接的ip /// /// public string GetIp() { IPEndPoint clientipe = (IPEndPoint)TcpSocket.RemoteEndPoint; string _ip = clientipe.Address.ToString(); return _ip; } /// /// 关闭连接 /// public void Close() { TcpSocket.Shutdown(SocketShutdown.Both); } /// /// 提取正确数据包 /// 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; } /// /// 添加队列数据 /// /// public void AddQueue(byte[] buffer) { m_Buffer.AddRange(buffer); } /// /// 清除缓存 /// public void ClearQueue() { m_Buffer.Clear(); } } } }