标签打印机抓包知识汇总
1. TCP抓包原理
1.1. TCP/IP协议
TCP/IP协议在一定程度上参考了OSI的体系结构。OSI模型共有七层,从下到上分别是物理层、数据链路层、网络层、运输层、会话层、表示层和应用层。但是这显然是有些复杂的,所以在TCP/IP协议中,它们被简化为了四个层次。
1、应用层、表示层、会话层三个层次提供的服务相差不是很大,所以在TCP/IP协议中,它们被合并为应用层一个层次。
2、由于运输层和网络层在网络协议中的地位十分重要,所以在TCP/IP协议中它们被作为独立的两个层次。
3、因为数据链路层和物理层的内容相差不多,所以在TCP/IP协议中它们被归并在网络接口层一个层次里。
- 建立连接:三次握手
- 关闭连接:四次挥手
1.2. WireShark使用
下载
https://www.wireshark.org/download.html
https://www.wireshark.org/download/win32/all-versions/
使用
为了更好的理解在整个TCP会话期间,TCP序列号和确认号是如何工作的,我们可以使用Wireshark内置的绘制流功能,选择菜单栏中的 Statistics ->Flow Graph...->TCP flow ->OK
Wireshark会自动创建一个TCP流的图形摘要
每行代表一个单独的TCP包,左边列显示时间,中间列显示包的方向、TCP端口、段长度和设置的标志位,右边列以10进制的方式显示相关序列号/确认号,在这里选中任意行会高亮主窗口中该行所关联的包
注:新版本中 统计 >> 流量图
1.3. 编程实现
WinPcap (windows packet captrue)
很多不同的工具软件使用Winpcap于网络分析,故障排除,网络安全监控等方面。Winpcap特别适用于下面这几个经典领域:
1、网络及协议分析
2、网络监控
3、通信日志记录
4、traffic generators
5、用户级别的桥路和路由
6、网络入侵检测系统(NIDS)
7、网络扫描
8、安全工具
Winpcap有些方面不能做。它不依靠主机的诸如TCP/IP协议去收发数据包。这意味着它不能阻塞,不能处理同一台主机中各程序之间的通信数据。它只能“嗅探”到物理线路上的数据包。因此它不适用于traffic shapers,QoS调度,以及个人防火墙。
https://baike.baidu.com/item/winpcap/11048966?fr=aladdin 介绍
https://www.winpcap.org/install/default.htm 下载
Npcap
Npcap是致力于采用Microsoft Light-Weight Filter (NDIS 6 LWF)技术和Windows Filtering Platform (NDIS 6 WFP)技术对当前最流行的WinPcap工具包进行改进的一个项目。Npcap项目是最初2013年由Nmap网络扫描器项目(创始人Gordon Lyon)和北京大学罗杨博士发起,由Google公司的Summer of Code计划赞助的一个开源项目,遵循MIT协议(与WinPcap一致)。Npcap基于WinPcap 4.1.3源码基础上开发,支持32位和64位架构,在Windows Vista以上版本的系统中,采用NDIS 6技术的Npcap能够比原有的WinPcap数据包(NDIS 5)获得更好的抓包性能,并且稳定性更好。
https://github.com/nmap/npcap/releases
1.4. 干扰
- 漏包
WinPcap抓取的数据有漏数据的情况
- 重包
重复传递某个数据包
- 提前到达
2. 打印机数据解析
2.1. 原理
TSC、Printronix、SATO、Citizen,数据的格式无非是点阵或者pcx,但是打印机一旦做了压缩算法,目前都无法解析
点阵图(TSC)
PCX 数据
2.2. 标签定位及解析
使用ZXing、DataMatrix.Net均会有解析失败的情况,为了捡漏(增加标签的识别率)使用二维码定位在解析的方式。
DataMatic格式的二维码,都有侧边有一个L型的边框,可以根据这个边框在一整张图片上来定位二维码。
3. 分布式
采集的数据先汇总到分厂的数据库,然后再通过数据库同步脚本,同步到中心服务器。
3.1. 集中日志
3.2. 机台运行程序
自动启动
把快捷方式通过vbs脚本添加到startup文件夹下
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 set WshShell=WScript.CreateObject("WScript.Shell") 2 strDesktop=WshShell.SpecialFolders("startup") 3 Msgbox strDesktop 4 currentPath=WshShell.CurrentDirectory 5 set oShellLink=WshShell.CreateShortcut(strDesktop & "\ApplicationName.lnk") 6 oShellLink.TargetPath=currentPath & "\ApplicationName.exe" 7 oShellLink.Arguments="/start" 8 oShellLink.WindowStyle=1 9 'oShellLink.Hotkey="CTRL+SHIFT+E" 10 'oShellLink.IconLocation="c:\mydocumentfolder\icon.ico,0" 11 oShellLink.Description="My Sniffer" 12 oShellLink.WorkingDirectory=currentPath 13 oShellLink.Save
自动最小化到托盘
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 WindowState = FormWindowState.Minimized; 2 3 /// <summary>初始化 右下角的通知栏(托盘)图标</summary> 4 private void initialTray() 5 { 6 notifyIcon1.Text = "开料辅助程序"; 7 notifyIcon1.MouseDoubleClick += notifyIcon1_MouseDoubleClick; 8 SizeChanged += F_Main_SizeChanged; 9 } 10 11 /// <summary> 12 /// 添加双击托盘图标事件(双击显示窗口) 13 /// </summary> 14 /// <param name="sender"></param> 15 /// <param name="e"></param> 16 private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e) 17 { 18 if (WindowState == FormWindowState.Minimized) 19 { 20 //还原窗体显示 21 WindowState = FormWindowState.Normal; 22 //激活窗体并给予它焦点 23 Activate(); 24 //任务栏区显示图标 25 ShowInTaskbar = true; 26 //托盘区图标隐藏 27 notifyIcon1.Visible = false; 28 } 29 } 30 31 /// <summary> 32 /// 判断是否最小化,然后显示托盘 33 /// </summary> 34 /// <param name="sender"></param> 35 /// <param name="e"></param> 36 private void F_Main_SizeChanged(object sender, EventArgs e) 37 { 38 //判断是否选择的是最小化按钮 39 if (WindowState == FormWindowState.Minimized) 40 { 41 //隐藏任务栏区图标 42 ShowInTaskbar = false; 43 //图标显示在托盘区 44 notifyIcon1.Visible = true; 45 } 46 }
本地时钟
从中心服务器获取当前时间,使用定时器进行累加
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public class LocalClockHelper 2 { 3 public delegate void OnLocalTimeChangeHandler(DateTime now); 4 5 private static DateTime _now; 6 private static readonly object _lock = new object(); 7 8 private static readonly SqlHelper _sqlHelper; 9 // private static System.Timers.Timer _timer; 10 11 static LocalClockHelper() 12 { 13 // 连接字符串 14 _sqlHelper = new SqlHelper(Global.ConnectionStrWithSettingIni); 15 16 // 定时从服务器上获取时间,初始化 17 _now = getTimeFromServer(); 18 StartTime = _now; 19 20 // 定时器 21 int index = 0; 22 ThreadManager.Instance.Loop("LocalClockHelper", () => 23 { 24 lock (_lock) 25 { 26 index++; 27 if (index > 60 * 60) 28 { 29 _now = getTimeFromServer(); 30 index = 0; 31 } 32 else 33 _now = _now.AddMilliseconds(1000); 34 35 OnLocalTimeChangeEvent?.Invoke(_now); 36 } 37 }, 1000); 38 39 } 40 41 /// <summary> 42 /// </summary> 43 public static DateTime Now 44 { 45 get 46 { 47 lock (_lock) 48 { 49 return _now; 50 } 51 } 52 } 53 54 /// <summary> 55 /// 系统启动时间 56 /// <remarks>不准确,但是好用</remarks> 57 /// </summary> 58 public static DateTime StartTime { get; } 59 60 public static event OnLocalTimeChangeHandler OnLocalTimeChangeEvent; 61 62 /// <summary> 63 /// 从服务器上获取时间 64 /// </summary> 65 private static DateTime getTimeFromServer() 66 { 67 try 68 { 69 // var now = DateTime.Now; 70 DateTime sqlDateTime = Convert.ToDateTime(_sqlHelper.ExecuteScalar("select getdate()")); 71 if (Math.Abs((sqlDateTime - DateTime.Now).TotalMilliseconds) < 1000) 72 return DateTime.Now; 73 return sqlDateTime; 74 } 75 catch (Exception exception) 76 { 77 NjEventLog.Instance.WriteFatal(exception); 78 } 79 80 return DateTime.Now; 81 } 82 83 /// <summary> 84 /// 重置 85 /// </summary> 86 public static void Reset() 87 { 88 lock (_lock) 89 { 90 _now = getTimeFromServer(); 91 } 92 } 93 }
禁止关闭
不足:无法阻止任务管理器上的强制关闭
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public MainForm(string[] args) 2 { 3 InitializeComponent(); 4 5 FormClosing += onFormClosing; 6 } 7 8 private void onFormClosing(object sender, FormClosingEventArgs e) 9 { 10 switch (e.CloseReason) 11 { 12 case CloseReason.ApplicationExitCall: //应用程序要求关闭窗口 13 case CloseReason.FormOwnerClosing: //自身窗口上的关闭按钮 14 case CloseReason.UserClosing: //用户通过UI关闭窗口或者通过Alt+F4关闭窗口 15 case CloseReason.MdiFormClosing: //MDI窗体关闭事件 16 case CloseReason.TaskManagerClosing: //任务管理器关闭进程 17 e.Cancel = true; //拦截,不响应操作 18 break; 19 20 case CloseReason.WindowsShutDown: //操作系统准备关机 21 e.Cancel = false; //不拦截,响应操作 22 break; 23 24 default: 25 case CloseReason.None: //不明原因的关闭 26 e.Cancel = true; //拦截,不响应操作 27 break; 28 } 29 //base.OnFormClosing(e); 30 }
自动更新
本地数据缓存
所有的数据先存到sqlite,然后再逐条进行上传
欢迎在评论区留下你宝贵的意见,不论好坏都是我前进的动力(cnblogs 排名提升)!
如果喜欢,记得点赞、推荐、关注、收藏、转发 ... ;)