之前负责过一个机场的项目,有一个环节是扫描登机牌,获取旅客信息的操作,当时是拟定了使用串口扫描枪来获取登机牌信息,后面用测试了网口的,这里记录一下当时用来测试网口使用的程序,供有需求的小伙伴们参考
1、设置全局参数,
private TcpClients _client;
private string _ip = '192.168.1.1';//扫描枪ip
private int _port = 4567;//扫描端口
private bool bCnt = false;
private bool t1Running = false;
private bool t2Running = false;
private static UdpClient client = new UdpClient(8081);//这边是通讯端口,如果有多个设备,这里需要改变
public Message_Scan data_ = new Message_Scan();
//检验是否断开链接或者断网
public bool client_Scan=false;//默认为断开链接
private System.Threading.Timer timer_heart;//定时器
2、存储扫描枪的类,防止连续发送
/// <summary>
/// 存储扫描枪数据
/// </summary>
public class Message_Scan
{
public string message { get; set; }
public DateTime CreateDatetime { get; set; }
}
3、主程序
data_.message = ""; //初始化消息
_client = new TcpClients();
_client.pushSockets = ReceiveMess;//注册推送器
client.JoinMulticastGroup(IPAddress.Parse("239.0.0.1"));
t2Running = true;
Thread t2 = new Thread(new ThreadStart(RecvThread2));
t2.IsBackground = true;
t2.Start();
ConnectSocket();
timer_heart = new System.Threading.Timer(new TimerCallback(MyDelegate_heart)); //实例化一个Timer时间器并启动,用来加载列表模版列数据
左边参数为方法开始的时间,右边为每此执行方法的时间间隔,下面的意思是,十秒后,每过十秒执行方法xxx
timer_heart.Change(15000, 15000);//15秒左右检测设备心跳,
/// <summary>
/// 连接Socket
/// </summary>
public void ConnectSocket()
{
try
{
string ip = _ip;
int port = _port;
_client.InitSocket(ip, port);
if (!bCnt)
{
_client.Start();
Logger.Info("连接成功");
bCnt = true;
}
else
{
_client.Stop();
Logger.Info("断开成功");
bCnt = false;
}
}
catch (Exception ex)
{
Logger.Info("链接失败");
}
}
//心跳方法
private void MyDelegate_heart(object state)
{
// 如果建立链接,会循环进入 ReceiveMess 方法,设置全局每次进入,修改全局为true,
//30s进入心跳,如果为true,则修改全局为false,否则,则表示没有进入ReceiveMess 方法,即可发送心跳
if (client_Scan==true)
{
client_Scan = false;//修改为未连接,用来检测是否断开链接
Logger.Info("通讯建立中");
}
else
{
//如果为false,则表示没有进入ReceiveMess方法,也就表示断开链接了
//这里可以自己业务进行处理
Logger.Info("通讯断开,即将发送心跳");
//准备重连
Logger.Info("进行重连中");
ConnectSocket();
}
}
/// <summary>
///接受线程
/// </summary>
private void RecvThread2()
{
IPEndPoint multicastin = new IPEndPoint(IPAddress.Parse("239.0.0.1"), 10001);
while (t2Running)
{
byte[] buf = client.Receive(ref multicastin);
string msg = Encoding.Default.GetString(buf);
string[] strList = msg.Split('&');
if (strList[0].Length > 0)
{
Logger.Info("strList" + strList[0]);
t1Running = false;
t2Running = false;
}
}
}
5、处理推送过来的消息
/// <summary>
/// 处理推送过来的消息
/// </summary>
/// <param name="rec"></param>
private void ReceiveMess(SocketHelper sks)
{
client_Scan = true; //每次进入都修改变量为已链接
if (sks.ex != null)
{
if (sks.ClientDispose == true)
{
Logger.Info("由于未知原因引发异常.导致客户端下线. 比如网络故障.或服务器断开连接.");
}
else
{
Logger.Info($"异常消息:{sks.ex}");
}
}
else if (sks.Offset == 0)
{
Logger.Info("客户端下线");
}
else
{
byte[] buffer = new byte[sks.Offset];
//需要和X4解码协议对应,参照协议文档
Array.Copy(sks.RecBuffer, buffer, sks.Offset);
if (buffer[4] != 0x00)
return;
int bcSize = 0;
byte[] bcszieBuf = new byte[4];
Array.Copy(buffer, 16, bcszieBuf, 0, 4);
bcSize = BitConverter.ToInt32(bcszieBuf, 0);
byte[] bcBuf = new byte[bcSize + 2];
Array.Copy(buffer, 20, bcBuf, 0, bcSize);
string str = Encoding.Default.GetString(bcBuf);
if (str != "" || str != null)
{
str = str.Replace("\r", "").Replace("\u0012", "");//去除特殊字符
str = str.Split('\0')[0].ToString(); //截取字符串,\0\0\0d
if (sks.Client.Client.Available > 0)//判断消息是否发送完成,socket的数据大小限制,分多个包发送
{
Logger.Info("s:" + str);
}
else
{
//处理扫描枪数据,比如重复发送
Processing_data(str);
}
}
else
{
Logger.Info("接受的消息长度为空或者为null值");
}
}
}
/// <summary>
/// 处理扫描枪数据
/// </summary>
/// <param name="str"></param>
public void Processing_data(string str)
{
if (data_.message == "" || data_.message == null)
{
data_.message = str;
data_.CreateDatetime = DateTime.Now;
Logger.Info(data_.message);
//这里就可以对数据进行处理了,比如发送给xxx设备
}
else if (data_.message == str)
{
//获取两者时间差
TimeSpan ts = DateTime.Now.Subtract(data_.CreateDatetime);
if (ts.TotalSeconds >= 7)
{
data_.message = str;
data_.CreateDatetime = DateTime.Now;
//这里就可以对数据进行处理了,比如发送给xxx设备
}
}
else
{
data_.message = str;
data_.CreateDatetime = DateTime.Now;
//这里就可以对数据进行处理了,比如发送给xxx设备
}
}
这里给大家安排一个tcp调试工具
链接:https://pan.baidu.com/s/1rm7KCbT8kUp0udXCHU9IfQ
提取码:mszd
如果链接失效的话,可以关注“墨水直达”公众号,回复“tcp调试工具”,即可获取最新下载链接哦
有朋友反馈说TcpClients类找不到,是我的疏忽,这里将公共类补上:
链接:https://pan.baidu.com/s/1ZuXoguHU5VNaRnp9RGg5xA
提取码:mszd
到时候直接将包解压放到项目中,引用就行