现在需要进一步学习多线程的知识,11年年初的时候写的程序,测试可以使用,但是对于多线程的机制还是不十分清楚,所以再拿出来看看。
1.读取Udp协议数据服务器端程序(图2):
(1)
(2)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
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 }
数据结构如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
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):
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
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 }