zoukankan      html  css  js  c++  java
  • 以前写的一个C#读取UDP协议数据包程序

      现在需要进一步学习多线程的知识,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                         try
    116                         {
    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                         finally
    127                         {
    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 ServerUdp
    17 {
    18     struct Head
    19     {
    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 error
    29         //用于说明本次数据是否有效,主要是用于被动模式下,当服务器请求数据,而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 StationID
    44     {
    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             #endregion
    104             try
    105             {
    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             finally
    120             {
    121             }
    122         }
    123         /// <summary>
    124         /// 将结构转换为字节数组
    125         /// </summary>
    126         /// <param name="obj">结构对象</param>
    127         /// <returns>字节数组</returns>
    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         /// <summary>
    146         /// byte数组转结构
    147         /// </summary>
    148         /// <param name="bytes">byte数组</param>
    149         /// <param name="type">结构类型</param>
    150         // <returns>转换后的结构</returns>
    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 }
    文章未经说明均属原创,学习笔记可能有大段的引用,一般会注明参考文献。 欢迎大家留言交流,转载请注明出处。
  • 相关阅读:
    Flink 1.14 新特性预览
    基于 MaxCompute 的实时数据处理实践
    Serverless 工程实践 | 细数 Serverless 的配套服务
    不得不看!虚拟货币和区块链的关系
    美国华尔街拥抱区块链是最大的威胁
    1.图片底部圆弧
    二、快捷键
    三、ASP.NET Core 部署Linux
    一、.NET Core MVC 项目结构模板
    一、纯css实现顶部进度条随滚动条滚动
  • 原文地址:https://www.cnblogs.com/yhlx125/p/2651893.html
Copyright © 2011-2022 走看看