以前写的一个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 }

 

posted @ 2012-08-23 09:38  太一吾鱼水  阅读(1147)  评论(0编辑  收藏  举报