让知识更加联贯
让技术走进生活
我的博客
我的程序
我的网络
------
郑紫至
E-mail:zhengzizhi@yahoo.com.cn
智能通道系统
本系统全面地展示了
Socket
与多线程,数据库,工业上采用的
CRC
查表校验信息码
等综合技术的完整代码,从代码的角度展示了工控通讯的完整过程,本系统可以改装成
地铁、火车站、海关、商场、旅游景点,智能小区、大型集团公司,大型停车场,
等等需要刷卡通行智能验证平台,本系统使用了软终端从理论的角度模拟出单片机终
端设备的通讯过程。
开发工具
:Visual Studio 2008.NET(C#) + Microsoft SQL Server 2005
智能通道系统之
(3)
Client[模拟单片机终端设备]
1
.设计模式下的界面截图
2. MainForm.cs
:
//******************************************************************************************
//
作者 :郑紫至
//
创建日期:2008-03-14
//
邮件地址:zhengzizhi@mail.china.com
//
博客地址:http://hi.csdn.net/zhengzizhi
//
备注说明:欢迎大家转载我的博客内容,代码版权归本人所有,请保留此信息。
//******************************************************************************************
using
System;
using
System.Collections.Generic;
using
System.ComponentModel;
using
System.Data;
using
System.Drawing;
using
System.Linq;
using
System.Text;
using
System.Windows.Forms;
using
System.Net.Sockets;
using
System.Net;
namespace
Client
{
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
#region
CRC16 Table Polynomial = 0xA001
byte[] CrcTableH8bit = {0x00,0xC0,0xC1,0x01,0xC3,0x03,0x02,0xC2,
0xC6,0x06,0x07,0xC7,0x05,0xC5,0xC4,0x04,
0xCC,0x0C,0x0D,0xCD,0x0F,0xCF,0xCE,0x0E,
0x0A,0xCA,0xCB,0x0B,0xC9,0x09,0x08,0xC8,
0xD8,0x18,0x19,0xD9,0x1B,0xDB,0xDA,0x1A,
0x1E,0xDE,0xDF,0x1F,0xDD,0x1D,0x1C,0xDC,
0x14,0xD4,0xD5,0x15,0xD7,0x17,0x16,0xD6,
0xD2,0x12,0x13,0xD3,0x11,0xD1,0xD0,0x10,
0xF0,0x30,0x31,0xF1,0x33,0xF3,0xF2,0x32,
0x36,0xF6,0xF7,0x37,0xF5,0x35,0x34,0xF4,
0x3C,0xFC,0xFD,0x3D,0xFF,0x3F,0x3E,0xFE,
0xFA,0x3A,0x3B,0xFB,0x39,0xF9,0xF8,0x38,
0x28,0xE8,0xE9,0x29,0xEB,0x2B,0x2A,0xEA,
0xEE,0x2E,0x2F,0xEF,0x2D,0xED,0xEC,0x2C,
0xE4,0x24,0x25,0xE5,0x27,0xE7,0xE6,0x26,
0x22,0xE2,0xE3,0x23,0xE1,0x21,0x20,0xE0,
0xA0,0x60,0x61,0xA1,0x63,0xA3,0xA2,0x62,
0x66,0xA6,0xA7,0x67,0xA5,0x65,0x64,0xA4,
0x6C,0xAC,0xAD,0x6D,0xAF,0x6F,0x6E,0xAE,
0xAA,0x6A,0x6B,0xAB,0x69,0xA9,0xA8,0x68,
0x78,0xB8,0xB9,0x79,0xBB,0x7B,0x7A,0xBA,
0xBE,0x7E,0x7F,0xBF,0x7D,0xBD,0xBC,0x7C,
0xB4,0x74,0x75,0xB5,0x77,0xB7,0xB6,0x76,
0x72,0xB2,0xB3,0x73,0xB1,0x71,0x70,0xB0,
0x50,0x90,0x91,0x51,0x93,0x53,0x52,0x92,
0x96,0x56,0x57,0x97,0x55,0x95,0x94,0x54,
0x9C,0x5C,0x5D,0x9D,0x5F,0x9F,0x9E,0x5E,
0x5A,0x9A,0x9B,0x5B,0x99,0x59,0x58,0x98,
0x88,0x48,0x49,0x89,0x4B,0x8B,0x8A,0x4A,
0x4E,0x8E,0x8F,0x4F,0x8D,0x4D,0x4C,0x8C,
0x44,0x84,0x85,0x45,0x87,0x47,0x46,0x86,
0x82,0x42,0x43,0x83,0x41,0x81,0x80,0x40};
byte[] CrcTableL8bit = {0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40};
#endregion
///<summary>
///
以查表法获得需要校验字节信息的16进制CRC码
///
表格数据的生成多项式CRC-16 Polynomial = 0xA001
///</summary>
///<param name="RequestToCheckBytes">
需要校验的字节数组
</param>
///<param name="RequestToCheckLengthOfBytes">
实际传入的字节数长度
</param>
///<returns>
返回一个高两位在前,低两位在后的16进制CRC码
</returns>
public string HexCrcCode(byte[] RequestToCheckBytes, int RequestToCheckLengthOfBytes)
{
int i, CrcTableIndex = 0;
byte CrcH8bit = 0x00, CrcL8bit = 0x00;
for (i = 0; i < RequestToCheckLengthOfBytes; i++)
{
if (RequestToCheckBytes[i] >= 0 && RequestToCheckBytes[i] < 255)
{
CrcTableIndex = RequestToCheckBytes[i] ^ CrcL8bit;
CrcL8bit = (byte)(CrcTableL8bit[CrcTableIndex] ^ CrcH8bit);
CrcH8bit = CrcTableH8bit[CrcTableIndex];
}
}
return CrcH8bit.ToString("x2").ToUpper() + CrcL8bit.ToString("x2").ToUpper();
}
byte[] BytesToServer = new byte[43];
string StringToServer = string.Empty;
byte[] EOFSignOfBytesToServer = new byte[11];
string EOFSignStringToServer = string.Empty;
private void btnSend_Click(object sender, EventArgs e)
{
if ((this.cmbCardNo.Text.Trim() != "") && (this.cmbCardMachineNo.Text.Trim() != ""))
{
string CardId = this.cmbCardNo.Text.Trim(); string MachinceId = this.cmbCardMachineNo.Text.Trim();
StringToServer = Convert.ToChar(0x03).ToString() +
Convert.ToInt32(MachinceId).ToString("x2").ToUpper() +
Convert.ToChar(0x4A).ToString() +
Convert.ToChar(0x41).ToString() +
Convert.ToChar(0x30).ToString() +
Convert.ToChar(0x31).ToString() +
Convert.ToChar(0x30).ToString() +
Convert.ToChar(0x30).ToString() +
Convert.ToChar(0x30).ToString() +
Convert.ToChar(0x30).ToString() +
Convert.ToChar(0x30).ToString() +
Convert.ToChar(0x30).ToString() +
Convert.ToChar(0x30).ToString() +
Convert.ToChar(0x30).ToString() +
Convert.ToChar(0x30).ToString() +
Convert.ToChar(0x30).ToString() +
Convert.ToInt32(CardId).ToString("x10").ToUpper() +
Convert.ToChar(0x30).ToString() +
Convert.ToChar(0x30).ToString() +
Convert.ToChar(0x30).ToString() +
Convert.ToChar(0x30).ToString() +
Convert.ToChar(0x30).ToString() +
Convert.ToChar(0x30).ToString() +
Convert.ToChar(0x30).ToString() +
Convert.ToChar(0x30).ToString() +
Convert.ToChar(0x30).ToString() +
Convert.ToChar(0x30).ToString() +
Convert.ToChar(0x30).ToString() +
Convert.ToChar(0x30).ToString() +
Convert.ToChar(0x30).ToString() +
Convert.ToChar(0x30).ToString() +
Convert.ToChar(0x30).ToString() +
Convert.ToChar(0x30).ToString();
BytesToServer = Encoding.Default.GetBytes(StringToServer);
EOFSignStringToServer = Convert.ToChar(0x03).ToString() +
Convert.ToInt32(MachinceId).ToString("x2").ToUpper() +
Convert.ToChar(0x30).ToString() +
Convert.ToChar(0x30).ToString() +
Convert.ToChar(0x30).ToString() +
Convert.ToChar(0x3C).ToString() +
Convert.ToChar(0x45).ToString() +
Convert.ToChar(0x4F).ToString() +
Convert.ToChar(0x46).ToString() +
Convert.ToChar(0x46).ToString();
EOFSignOfBytesToServer = Encoding.Default.GetBytes(EOFSignStringToServer);
CardMachineBeginSendAndReceiveData();
}
else
{
MessageBox.Show("/r/n
请选择卡机和卡号通行."
, "
提示信息"
, MessageBoxButtons.OK, MessageBoxIcon.Question);
}
}
private Socket ClientSocket;
///<summary>
///
保存客户端卡机收到服务器发过来的字节(第0位至第7位)
///</summary>
byte[] SaveInterceptFromServerBytes = new byte[8];
///<summary>
///
客户端卡机收到服务器发过来的CRC码
///</summary>
string SaveInterceptFromServerHexCrcCode;
///<summary>
///
保存字节转换成字符串的变量(格式:信息码8位 + CRC码4位十六进制字符 + 末位0x0D(换行符))
///</summary>
string SaveFromServerBytesToString = string.Empty ;
private void CardMachineBeginSendAndReceiveData()
{
string Ip = this.txtIp.Text;
string Port = this.txtPort.Text;
IPAddress ServerIp = IPAddress.Parse(Ip);
int ServerPort = Convert.ToInt32(Port);
IPEndPoint iep = new IPEndPoint(ServerIp, ServerPort);
ClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
ClientSocket.Connect(iep);
//
ClientSocket.Send(BytesToServer);
byte[] ReceivedFromServerBytes = new byte[100];
int ReceivedFromServerBytesLength = ClientSocket.Receive(ReceivedFromServerBytes);
for (int i = 0; i < ReceivedFromServerBytesLength; i++)
{
//
截取第0位至第7位代表的信息码
if (i < 8)
{
SaveInterceptFromServerBytes[i] = ReceivedFromServerBytes[i];
}
//
截取第8位,第9位,第10位和第11位代表CRC码
if ((i > 7) && (i < 12))
{
SaveInterceptFromServerHexCrcCode += Convert.ToChar(ReceivedFromServerBytes[i]);
}
//
字节转字符串其结果将用来显示在 ListBox 中
SaveFromServerBytesToString += "0x" + ReceivedFromServerBytes[i].ToString("x2").ToUpper() + " ";
}
//
比较服务端软编码与卡机数字电路得出的 CRC校验码是否相等
if (HexCrcCode(SaveInterceptFromServerBytes, 8) != SaveInterceptFromServerHexCrcCode)
{
this.lblDispaly.Text = "
×"
;
this.lblDispaly.ForeColor = Color.Red;
MessageBox.Show("/r/nCRC
校验出错"
, "
错误信息"
, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
//
第5位和第6位为卡机读头编号 04(0x30 0x34)代表非正常通行
if ((SaveInterceptFromServerBytes[5] == 0x30) && (SaveInterceptFromServerBytes[6] == 0x34))
{
this.lblDispaly.Text = "
×"
;
this.lblDispaly.ForeColor = Color.Red;
}
else
{
this.lblDispaly.Text = "
↑"
;
}
}
//listBoxResult
中显示 0x + 收到来自服务器发来的16进制数
listBoxResult.Items.Add(SaveFromServerBytesToString);
//
客户端卡机第二次发送<EOF>标示给服务器
//
告诉服务器让服务结束一次完整的通讯过程
ClientSocket.Send(EOFSignOfBytesToServer);
//
清空变量让给下一次完整通讯使用
SaveInterceptFromServerHexCrcCode = string.Empty;
//
清空变量让给下一次完整通讯使用
SaveFromServerBytesToString = string.Empty;
}
private void timer1_Tick(object sender, EventArgs e)
{
//
清空显示屏,模拟通行指示标记复位;
//
通行标记显示 5 秒后,然后自动清空。
this.lblDispaly.Text = string.Empty ;
}
}
}
2. MainForm.Designer.cs
:
namespace
Client
{
partial class MainForm
{
///<summary>
/// Required designer variable.
///</summary>
private System.ComponentModel.IContainer components = null;
///<summary>
/// Clean up any resources being used.
///</summary>
///<param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
try
{
ClientSocket.Shutdown(System.Net.Sockets.SocketShutdown.Both);
ClientSocket.Close();
}
catch
{ }
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region
Windows Form Designer generated code
///<summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///</summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.btnSend = new System.Windows.Forms.Button();
this.cmbCardNo = new System.Windows.Forms.ComboBox();
this.label4 = new System.Windows.Forms.Label();
this.cmbCardMachineNo = new System.Windows.Forms.ComboBox();
this.label3 = new System.Windows.Forms.Label();
this.txtPort = new System.Windows.Forms.TextBox();
this.label2 = new System.Windows.Forms.Label();
this.txtIp = new System.Windows.Forms.TextBox();
this.label1 = new System.Windows.Forms.Label();
this.groupBox2 = new System.Windows.Forms.GroupBox();
this.listBoxResult = new System.Windows.Forms.ListBox();
this.lblDispaly = new System.Windows.Forms.Label();
this.timer1 = new System.Windows.Forms.Timer(this.components);
this.groupBox1.SuspendLayout();
this.groupBox2.SuspendLayout();
this.SuspendLayout();
//
// groupBox1
//
this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.groupBox1.Controls.Add(this.lblDispaly);
this.groupBox1.Controls.Add(this.btnSend);
this.groupBox1.Controls.Add(this.cmbCardNo);
this.groupBox1.Controls.Add(this.label4);
this.groupBox1.Controls.Add(this.cmbCardMachineNo);
this.groupBox1.Controls.Add(this.label3);
this.groupBox1.Controls.Add(this.txtPort);
this.groupBox1.Controls.Add(this.label2);
this.groupBox1.Controls.Add(this.txtIp);
this.groupBox1.Controls.Add(this.label1);
this.groupBox1.Location = new System.Drawing.Point(12, 4);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(490, 86);
this.groupBox1.TabIndex = 0;
this.groupBox1.TabStop = false;
this.groupBox1.Text = "
客户端Socket"
;
//
// btnSend
//
this.btnSend.Location = new System.Drawing.Point(402, 46);
this.btnSend.Name = "btnSend";
this.btnSend.Size = new System.Drawing.Size(75, 23);
this.btnSend.TabIndex = 8;
this.btnSend.Text = "
模拟刷卡"
;
this.btnSend.UseVisualStyleBackColor = true;
this.btnSend.Click += new System.EventHandler(this.btnSend_Click);
//
// cmbCardNo
//
this.cmbCardNo.FormattingEnabled = true;
this.cmbCardNo.Items.AddRange(new object[] {
"0013776138",
"0008619437",
"0000198062",
"0001031159",
"0010504946"});
this.cmbCardNo.Location = new System.Drawing.Point(227, 48);
this.cmbCardNo.Name = "cmbCardNo";
this.cmbCardNo.Size = new System.Drawing.Size(99, 20);
this.cmbCardNo.TabIndex = 7;
//
// label4
//
this.label4.AutoSize = true;
this.label4.Location = new System.Drawing.Point(173, 51);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(41, 12);
this.label4.TabIndex = 6;
this.label4.Text = "ID
卡号"
;
//
// cmbCardMachineNo
//
this.cmbCardMachineNo.FormattingEnabled = true;
this.cmbCardMachineNo.Items.AddRange(new object[] {
"01",
"02",
"03",
"04",
"05",
"06",
"07",
"08",
"09",
"10",
"11",
"12"});
this.cmbCardMachineNo.Location = new System.Drawing.Point(64, 48);
this.cmbCardMachineNo.Name = "cmbCardMachineNo";
this.cmbCardMachineNo.Size = new System.Drawing.Size(100, 20);
this.cmbCardMachineNo.TabIndex = 5;
this.cmbCardMachineNo.Text = "01";
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(6, 52);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(53, 12);
this.label3.TabIndex = 4;
this.label3.Text = "
卡机编号"
;
//
// txtPort
//
this.txtPort.Location = new System.Drawing.Point(226, 23);
this.txtPort.Name = "txtPort";
this.txtPort.Size = new System.Drawing.Size(100, 21);
this.txtPort.TabIndex = 3;
this.txtPort.Text = "8000";
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(167, 26);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(53, 12);
this.label2.TabIndex = 2;
this.label2.Text = "
通讯端口"
;
//
// txtIp
//
this.txtIp.Location = new System.Drawing.Point(63, 23);
this.txtIp.Name = "txtIp";
this.txtIp.Size = new System.Drawing.Size(100, 21);
this.txtIp.TabIndex = 1;
this.txtIp.Text = "192.168.1.91";
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(12, 26);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(41, 12);
this.label1.TabIndex = 0;
this.label1.Text = "
终端IP"
;
//
// groupBox2
//
this.groupBox2.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.groupBox2.Controls.Add(this.listBoxResult);
this.groupBox2.Location = new System.Drawing.Point(12, 96);
this.groupBox2.Name = "groupBox2";
this.groupBox2.Size = new System.Drawing.Size(490, 207);
this.groupBox2.TabIndex = 1;
this.groupBox2.TabStop = false;
this.groupBox2.Text = "
服务器Socket完成一次完整通讯返回的信息"
;
//
// listBoxResult
//
this.listBoxResult.Dock = System.Windows.Forms.DockStyle.Fill;
this.listBoxResult.FormattingEnabled = true;
this.listBoxResult.HorizontalScrollbar = true;
this.listBoxResult.ItemHeight = 12;
this.listBoxResult.Location = new System.Drawing.Point(3, 17);
this.listBoxResult.Name = "listBoxResult";
this.listBoxResult.ScrollAlwaysVisible = true;
this.listBoxResult.Size = new System.Drawing.Size(484, 184);
this.listBoxResult.TabIndex = 0;
//
// lblDispaly
//
this.lblDispaly.BackColor = System.Drawing.Color.Black;
this.lblDispaly.Font = new System.Drawing.Font("SimSun", 36F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.lblDispaly.ForeColor = System.Drawing.Color.Lime;
this.lblDispaly.Location = new System.Drawing.Point(332, 21);
this.lblDispaly.Name = "lblDispaly";
this.lblDispaly.Size = new System.Drawing.Size(40, 49);
this.lblDispaly.TabIndex = 9;
this.lblDispaly.TextAlign = System.Drawing.ContentAlignment.TopCenter;
//
// timer1
//
this.timer1.Enabled = true;
this.timer1.Interval = 5000;
this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
//
// MainForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(514, 307);
this.Controls.Add(this.groupBox2);
this.Controls.Add(this.groupBox1);
this.Name = "MainForm";
this.Text = "
智能通道系统 - 模拟终端[客户端]"
;
this.groupBox1.ResumeLayout(false);
this.groupBox1.PerformLayout();
this.groupBox2.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.TextBox txtPort;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.TextBox txtIp;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.GroupBox groupBox2;
private System.Windows.Forms.Button btnSend;
private System.Windows.Forms.ComboBox cmbCardNo;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.ComboBox cmbCardMachineNo;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.ListBox listBoxResult;
private System.Windows.Forms.Label lblDispaly;
private System.Windows.Forms.Timer timer1;
}
}
Client
项目所有代码全部发布完毕(包括自动生成的代码)