博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
以前写的一个C#读取UDP协议数据包程序
阅读量:7053 次
发布时间:2019-06-28

本文共 16853 字,大约阅读时间需要 56 分钟。

  现在需要进一步学习多线程的知识,11年年初的时候写的程序,测试可以使用,但是对于多线程的机制还是不十分清楚,所以再拿出来看看。

1.读取Udp协议数据服务器端程序(图2):

 (1) (2)

View Code
1 using System;  2 using System.Collections.Generic;  3 using System.ComponentModel;  4 using System.Data;  5 using System.Drawing;  6 using System.Text;  7 using System.Windows.Forms;  8 using System.Runtime.InteropServices;  9 using System.Net; 10 using System.Net.Sockets; 11 using System.Threading; 12  13 namespace ServerUdp 14 { 15     public partial class Serverfrm : Form 16     { 17         UdpClient udpReceive; 18         private Thread myThread; 19         private delegate void SetlistBoxCallBack(string str);//委托, 20         private SetlistBoxCallBack setlistbox; 21         22         public Serverfrm() 23         { 24             InitializeComponent(); 25         } 26  27         private void Serverfrm_Load(object sender, EventArgs e) 28         { 29             setlistbox = new SetlistBoxCallBack(SetListBox); 30         } 31         private void ReceiveMessage() 32         { 33            // mDB_means.Open(); 34             byte[] ReceiveBytes = null; 35             IPEndPoint remoteIpEndIPoint = new IPEndPoint(IPAddress.Any, 29527); 36             udpReceive = new UdpClient(remoteIpEndIPoint); 37             IPEndPoint iep = new IPEndPoint(IPAddress.Any, 0); 38             while (true) 39             { 40                 try 41                 { 42                     ReceiveBytes = udpReceive.Receive(ref iep); 43                 } 44                 catch (Exception ex) 45                 { 46                     MessageBox.Show(ex.ToString()); 47                     return; 48                 } 49                 finally 50                 { 51                 } 52                 int pPoint = 0; 53                 string message = "来自" + iep.ToString() + "的消息"; 54                 Head phead = new Head(); 55                 System.Type ptype = phead.GetType(); 56                 phead = (Head)BytesToStruct(ReceiveBytes, ptype, 0); 57                 pPoint +=Marshal.SizeOf(phead); 58  59                 StationID apid = new StationID(); 60                 System.Type ptype1 = apid.GetType(); 61                 apid = (StationID)BytesToStruct(ReceiveBytes, ptype1, pPoint); 62                 pPoint +=Marshal.SizeOf(apid ); 63  64                 listBox1.Invoke(setlistbox, message); 65                  66                 int p=0; 67                 foreach (byte flg in phead.flag) 68                 { 69                     if (flg != '\0') 70                         p++; 71                 } 72                 byte[] tempbyte = new byte[p]; 73                 for (int i = 0; i < p; i++) 74                     tempbyte[i] = phead.flag[i]; 75  76                 string export =Encoding.UTF8.GetString (tempbyte ) + " " + phead.len.ToString() + " " + phead.type.ToString() + " " + phead.cmd.ToString() + " " + phead.rc.ToString(); 77                 listBox1.Invoke(setlistbox, export); 78                 listBox1.Invoke(setlistbox, Encoding.UTF8.GetString(apid.serial)); 79                  80                 if (phead.cmd  == 2) 81                 { 82                     PacketData pPacketData = new PacketData(); 83                     int ind=Convert.ToInt16 ((phead.len -pPoint)/Marshal.SizeOf (pPacketData )) ; 84                     System.Type ptype2 = pPacketData.GetType(); 85                     86                     for (int i = 1; i <= ind; i++) 87                     { 88                         pPacketData = (PacketData)BytesToStruct(ReceiveBytes, ptype2, pPoint); 89                         pPoint += Marshal.SizeOf(pPacketData); 90                          string addrstr1 = ""; 91                     foreach (byte tele in pPacketData.Kid ) 92                     { 93                         addrstr1 += Convert.ToString(tele); 94                     } 95                         listBox1.Invoke(setlistbox, addrstr1 + " " + pPacketData.rssi.ToString() + " " + pPacketData.time.ToString()); 96                        // listBox1.Invoke(setlistbox, pPacketData.Kid + " " + pPacketData.rssi.ToString() + " " + pPacketData.time.ToString()); 97                        98                     } 99                 }100                 else if (phead.cmd  == 1)101                 {102                     WifiData pWifiData = new WifiData();103                     int ind = Convert.ToInt16((phead.len - pPoint) / Marshal.SizeOf(pWifiData));104                     System.Type ptype3 = pWifiData.GetType();105                     for (int i = 1; i <= ind; i++)106                     {107                         pWifiData = (WifiData)BytesToStruct(ReceiveBytes, ptype3, pPoint);108                         pPoint += Marshal.SizeOf(pWifiData);109                         string addrstr = "";110                         foreach (byte bele in  pWifiData.addr)111                         {112                             addrstr +=bele.ToString("X")+":" ;113                         }114                         listBox1.Invoke(setlistbox, addrstr + " " + pWifiData.rssi.ToString() + " " + pWifiData.rate.ToString() + " " + pWifiData.time.ToString());115                         try116                         {117 118                             //  string SQL = "insert into 接收AP信息 values('" + Encoding.UTF8.GetString(pPacketData.Kid) + "','" + pPacketData.rssi + "','" + pPacketData.time + "','" + Encoding.UTF8.GetString(apid.serial) + "')";119                             // int ii = mDB_means.Operate(SQL);120 121                         }122                         catch (Exception ex)123                         {124 125                         }126                         finally127                         {128                             //continue;129                         }130                     }131                 }132                 133                 //AddKaoQ(list1, phead);//将接收的数据转换成需要的考勤信息数组和位置解算数组134                 //Store(list1);135             }136            137         }138         private void SetListBox(string str)139         {140             listBox1.Items.Add(str);141             listBox1.SelectedIndex = listBox1.Items.Count - 1;142             listBox1.ClearSelected();143         }144         private void btnStop_Click(object sender, EventArgs e)145         {146            147             btnStart.Enabled = true;148             udpReceive.Close ();149             myThread.Abort();150         }151 152         private void Serverfrm_FormClosed(object sender, FormClosedEventArgs e)153         {154             udpReceive.Close();155             myThread.Abort();156         }157         public object BytesToStruct(byte[] bytes, Type type, int p)158         {159             //得到结构的大小160             int size = Marshal.SizeOf(type);161             //Log(size.ToString(), 1);162             //byte数组长度小于结构的大小163             if (size > bytes.Length)164             {165                 //返回空166                 return null;167             }168             //分配结构大小的内存空间169             IntPtr structPtr = Marshal.AllocHGlobal(size);170             //将byte数组拷到分配好的内存空间171             Marshal.Copy(bytes, p, structPtr, size);172             //将内存空间转换为目标结构173             object obj = Marshal.PtrToStructure(structPtr, type);174             //释放内存空间175             Marshal.FreeHGlobal(structPtr);176             //返回结构177             return obj;178         }179 180         private void btnStart_Click(object sender, EventArgs e)181         {182             btnStart.Enabled = false;183             184             myThread = new Thread(new ThreadStart(ReceiveMessage));185             myThread.Start();186            187         }188 189       190 191        192     }193 }

数据结构如下:

数据包数据结构
1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Drawing; 6 using System.Text; 7 using System.Windows.Forms; 8 using System.Net; 9 using System.Net.Sockets;10 using System.Runtime.InteropServices;11 //System.Runtime.InteropServices 命名空间提供各种各样支持 COM interop 及平台调用服务的成员12 //此命名空间提供了多种类别的功能,如下表所示。13 //属性可控制封送行为,例如如何安排结构或表示字符串。14 //其中最重要的属性有 DllImportAttribute(可以用来定义用于访问非托管 API 的平台调用方法)和 15 //MarshalAsAttribute(可以用来指定如何在托管内存与非托管内存之间封送数据)。16 namespace ServerUdp17 {18     struct Head19     {20         //head头长为12 字节21         [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]22         public byte[] flag;        //AQD,用来标志数据,默认值为“AQD”,4个字节23         public uint len;    //all transimit len,用来表示整个数据头和数据部分的总,长度4个字节24         public byte type;   //packet type, 0: request 1: respond 2:report,数据类型,1个字节25         //packet command1:代表 wifi 手机的数据2:代表 人员定位卡的数据26         public sbyte cmd;   //1个字节27        28         //return code, 0 correct, other error29         //用于说明本次数据是否有效,主要是用于被动模式下,当服务器请求数据,而AP应答时,说明数据是否请求成功,或者表示错误的代码,30         //主动模式下没有意义。此值为两个字节长,默认值为0。31         public UInt16  rc;//2 个字节32 33         34     }35     public struct PacketData//人员定位卡数据36     {37         [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]38         public byte[] Kid;//人员定位卡号码,3个字节39         public byte  rssi;//信号强度1字节40         public uint time;//获取信号的时间,4个字节,其中时间的表示为从2010-1-1-0:00到取得信号时的间隔秒数41         42     }43     struct StationID44     {45         [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]46         public byte[] serial;47     }48     public struct WifiData//Wifi手机数据49     {50         [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]51         public Byte[] addr;//WIFI 模块MAC,6字节52         public sbyte    rssi;//信号强度,1字节53         public byte rate;//模块的通讯速度,1字节54         public uint time;//获取信号的时间,4字节,其中时间的表示为从2010-1-1-0:00到取得信号时的间隔秒数55        56     }57 }

 2.发送数据测试程序(图1):

View Code
1 using System;  2 using System.Collections.Generic;  3 using System.ComponentModel;  4 using System.Data;  5 using System.Drawing;  6 using System.Text;  7 using System.Windows.Forms;  8 using System.Collections;  9 using System.Net; 10 using System.Net.Sockets; 11 using System.Runtime.InteropServices; 12  13 namespace ApUdp 14 { 15     public partial class Apfrm : Form 16     { 17         UdpClient udpSend; 18         public Apfrm() 19         { 20             InitializeComponent(); 21         } 22  23         private void button1_Click(object sender, EventArgs e) 24         { 25             //DateTime pdatetime = new DateTime(); 26             //DateTime PdateTime = new DateTime(2010, 1, 1); 27             //pdatetime = DateTime.Now; 28             //TimeSpan   aa = pdatetime - PdateTime; 29             //MessageBox.Show(aa.TotalDays.ToString() + " " + aa.TotalHours.ToString() + " " + Convert .ToString (aa.TotalDays *24) + " " + aa.TotalSeconds.ToString()); 30              31             timer1.Enabled = !timer1.Enabled; 32              33         } 34          35         private void timer1_Tick(object sender, EventArgs e) 36         {         37             //基站编号 38             StationID apid = new StationID(); 39             //apid.serial =new byte[]{1,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0}; 40             apid.serial = Encoding.UTF8.GetBytes(new char[] { 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'a', 'p', '0', '1' }); 41  42             DateTime pNowTime = new DateTime(); 43             DateTime pDateTime = new DateTime(2010, 1, 1); 44             pNowTime = DateTime.Now; 45             TimeSpan pTimeSpan = pNowTime - pDateTime;//时间间隔 46  47             //定位卡数据2份 48             PacketData pPacketData1 = new PacketData(); 49             pPacketData1.Kid = Encoding.UTF8.GetBytes("k01"); 50             pPacketData1.rssi = 1; 51             pPacketData1.time =Convert .ToUInt32 ( pTimeSpan.TotalSeconds); 52  53             PacketData pPacketData2 = new PacketData(); 54             pPacketData2.Kid = Encoding.UTF8.GetBytes("k02"); 55             pPacketData2.rssi = 1; 56             pPacketData2.time =Convert.ToUInt32 ( pTimeSpan.TotalSeconds); 57  58             PacketData pPacketData3 = new PacketData(); 59             pPacketData3.Kid = Encoding.UTF8.GetBytes("k03"); 60             pPacketData3.rssi = 2; 61             pPacketData3.time = Convert.ToUInt32(pTimeSpan.TotalSeconds); 62  63             //头数据 64             Head headap1 = new Head(); 65             //headap1.flag = new byte[] { (byte)'A', (byte)'P', 0, 1 }; 66             headap1.flag = Encoding.UTF8.GetBytes(new char[] { 'A', 'D', 'Q', ' ' }); 67             headap1.len = Convert.ToUInt32( Marshal.SizeOf(headap1)+Marshal.SizeOf (apid )+2*Marshal.SizeOf (pPacketData1)) ; 68             headap1.type = 2;//标识主动上报 69             headap1.cmd = 2;//表示Wifi手机 70             headap1.rc = 0;//默认为0 71  72             byte[] aa = StructToBytes(headap1);//转换成字节数组 73             byte[] bb = StructToBytes(apid  );//转换成字节数组 74             byte[] cc = StructToBytes(pPacketData1);//转换成字节数组 75             byte[] dd = StructToBytes(pPacketData2);//转换成字节数组 76  77             byte[] SendBytes =new byte[headap1.len ];//转换成字节数组 78             aa.CopyTo(SendBytes, 0); 79             bb.CopyTo(SendBytes, aa.Length ); 80             cc.CopyTo(SendBytes, aa.Length  + bb.Length ); 81             dd.CopyTo(SendBytes, aa.Length +cc.Length  + bb.Length ); 82  83             System.Type ptype = headap1.GetType(); 84             Head TestBytesbb = (Head)BytesToStruct(SendBytes, ptype,0); 85             System.Type ptype1 =apid.GetType(); 86             StationID TestBytes = (StationID)BytesToStruct(SendBytes, ptype1, Marshal.SizeOf (TestBytesbb)); 87             #region 利用Arraylist尝试 88             //ArrayList parraylist = new ArrayList(); 89             //parraylist.Add(headap1); 90             //parraylist.Add(apid); 91             //parraylist.Add(pPacketData1); 92             //parraylist.Add(pPacketData2); 93  94             //byte[] aa = StructToBytes(headap1);//转换成字节数组 95             //System.Type ptype1 = headap1.GetType(); 96             //Head bb = (Head)BytesToStruct(aa, ptype1); 97  98             //byte[] SendBytes = StructToBytes(parraylist );//转换成字节数组 99             //System.Type ptype = parraylist.GetType();100             //Head TestBytes = (Head)BytesToStruct(SendBytes, ptype);101 102             //MessageBox.Show(headap1.len .ToString ()+" "+SendBytes.Length .ToString ());103             #endregion104             try105             {106                 udpSend = new UdpClient();107                 IPAddress remoteIPAddress = IPAddress.Parse("127.0.0.1");108                 IPEndPoint remoteIPEndPoint = new IPEndPoint(remoteIPAddress, 29527);109                 udpSend.Send(SendBytes, SendBytes.Length, remoteIPEndPoint);110 111                 listBox1.Items.Add(Encoding.UTF8.GetString(TestBytesbb.flag) + " " + TestBytesbb.len.ToString() + " " + TestBytesbb.type.ToString() + " " + TestBytesbb.cmd.ToString() + " " + TestBytesbb.rc.ToString());112                 listBox1.Items.Add(Encoding.UTF8 .GetString(TestBytes.serial));113             }114             catch (Exception ex)115             {116                 MessageBox.Show(ex.ToString());117                 return;118             }119             finally120             {121             }122         }123         /// 124         /// 将结构转换为字节数组125         /// 126         /// 结构对象127         /// 
字节数组
128 public byte[] StructToBytes(object obj)129 {130 //得到结构体的大小131 int size = Marshal.SizeOf(obj);132 //创建byte数组133 byte[] bytes = new byte[size];134 //分配结构体大小的内存空间135 IntPtr structPtr = Marshal.AllocHGlobal(size);136 //将结构体拷到分配好的内存空间137 Marshal.StructureToPtr(obj, structPtr, false);138 //从内存空间拷到byte数组139 Marshal.Copy(structPtr, bytes, 0, size);140 //释放内存空间141 Marshal.FreeHGlobal(structPtr);142 //返回byte数组143 return bytes;144 }145 /// 146 /// byte数组转结构147 /// 148 /// byte数组149 /// 结构类型150 //
转换后的结构
151 public object BytesToStruct(byte[] bytes,Type type ,int p)152 {153 //得到结构的大小154 int size = Marshal.SizeOf(type);155 //Log(size.ToString(), 1);156 //byte数组长度小于结构的大小157 if (size > bytes.Length)158 {159 //返回空160 return null;161 }162 //分配结构大小的内存空间163 IntPtr structPtr = Marshal.AllocHGlobal(size);164 //将byte数组拷到分配好的内存空间165 Marshal.Copy (bytes, p, structPtr, size);166 //将内存空间转换为目标结构167 object obj = Marshal.PtrToStructure(structPtr, type);168 //释放内存空间169 Marshal.FreeHGlobal(structPtr);170 //返回结构171 return obj;172 }173 174 }175 }

 

转载于:https://www.cnblogs.com/yhlx125/archive/2012/08/23/2651893.html

你可能感兴趣的文章
安卓开发_慕课网_百度地图_实现定位
查看>>
【POJ】1228 Grandpa's Estate(凸包)
查看>>
【百度地图API】建立全国银行位置查询系统(四)——如何利用百度地图的数据生成自己的标注...
查看>>
OpenGL中的功能与OSG对应功能 (摘)
查看>>
XMPP协议的原理介绍
查看>>
面向对象3大特性的简单理解
查看>>
备机大地院系项目dataguard archived_log及standby_log
查看>>
Spring_Task初探(注解,XML配置)
查看>>
MyEclipse 2015优化技巧
查看>>
众推项目的最近讨论
查看>>
SD卡兼容性问题(转)
查看>>
解决ecshop登陆自动退出的莫名现象
查看>>
面试之求找两个数和为某个数、几个连续数等于某个数
查看>>
【LaTeX排版】LaTeX纸排版&lt;两&gt;
查看>>
C/C++函数调用方式
查看>>
Timer Swing
查看>>
Cassandra命令行CLI的基本使用
查看>>
JQuery获取浏览器窗口的可视区域高度和宽度,滚动条高度
查看>>
8、redis之事务1-redis命令
查看>>
http://www.111cn.net/jsp/Jsp-Servlet/45158.htm
查看>>