742 lines
26 KiB
C#
742 lines
26 KiB
C#
|
|
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();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|