智能通道系统之(1)Server

 

让知识更加联贯 让技术走进生活
我的博客        我的程序 我的网络
               ------ 郑紫至
               E-mail:zhengzizhi@yahoo.com.cn
智能通道系统
本系统全面地展示了 Socket 与多线程,数据库,工业上采用的 CRC 查表校验信息码
等综合技术的完整代码,从代码的角度展示了工控通讯的完整过程,本系统可以改装成
  地铁、火车站、海关、商场、旅游景点,智能小区、大型集团公司,大型停车场,
等等需要刷卡通行智能验证平台,本系统使用了软终端从理论的角度模拟出单片机终
端设备的通讯过程。
开发工具 :Visual Studio 2008.NET(C#) + Microsoft SQL Server 2005
 
智能通道系统之 (1)Server
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;
using System.Net.Sockets;
using System.Threading;
using System.Data.SqlClient;
using System.Configuration;
 
namespace Server
{
    public partial class MainForm : Form
    {
        public static ListBox TopListBox;
        public static ListBox MiddleListBox;
        public static ListBox BottomListBox;
        ///<summary>
        /// IsServerSocketRunning 默认为执行状态
        ///</summary>
        bool IsServerSocketRunning = true;
        public static PictureBox[] PictureBoxArray;
        public static Label[] LabelArray;
        public static PictureBox ConnectedPictureBox;
        public static PictureBox DisconnectedPictureBox;
        int ServerPromgramRunningSeconds = 0;
        int MachineCount = 0;
        Thread ThreadOfStartServerSocketListening;
        Socket ServerSocket;
        private Socket SocketOfNewlyConnection;
 
        public MainForm()
        {
            InitializeComponent();
            InitStaticListBoxes();
          
        }
 
        private void InitStaticListBoxes()
        {
            TopListBox = new ListBox(); 
            MiddleListBox = new ListBox();
            BottomListBox = new ListBox();
          
            //
            // TopListBox
            //
            TopListBox.BackColor = System.Drawing.Color.Black;
            TopListBox.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
            TopListBox.Dock = System.Windows.Forms.DockStyle.Top;
            TopListBox.Font = new System.Drawing.Font("PMingLiU", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(136)));
            TopListBox.ForeColor = System.Drawing.Color.Lime;
            TopListBox.FormattingEnabled = true;
            TopListBox.HorizontalScrollbar = true;
            TopListBox.ItemHeight = 12;
            TopListBox.Location = new System.Drawing.Point(3, 3);
            TopListBox.Name = "TopListBox";
            TopListBox.ScrollAlwaysVisible = true;
            TopListBox.Size = new System.Drawing.Size(748, 170);
            TopListBox.TabIndex = 4;
            //
            // MiddleListBox
            //
            MiddleListBox.BackColor = System.Drawing.Color.Black;
            MiddleListBox.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
            MiddleListBox.Dock = System.Windows.Forms.DockStyle.Top;
            MiddleListBox.Font = new System.Drawing.Font("PMingLiU", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(136)));
            MiddleListBox.ForeColor = System.Drawing.Color.Lime;
            MiddleListBox.FormattingEnabled = true;
            MiddleListBox.HorizontalScrollbar = true;
            MiddleListBox.ItemHeight = 12;
            MiddleListBox.Location = new System.Drawing.Point(4, 173);
            MiddleListBox.Name = "MiddleListBox";
            MiddleListBox.ScrollAlwaysVisible = true;
            MiddleListBox.Size = new System.Drawing.Size(747, 170);
            MiddleListBox.TabIndex = 5;
            //
            // BottomListBox
            //
            BottomListBox.BackColor = System.Drawing.Color.Black;
            BottomListBox.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
            BottomListBox.Dock = System.Windows.Forms.DockStyle.Fill;
            BottomListBox.Font = new System.Drawing.Font("PMingLiU", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(136)));
            BottomListBox.ForeColor = System.Drawing.Color.Lime;
            BottomListBox.FormattingEnabled = true;
            BottomListBox.HorizontalScrollbar = true;
            BottomListBox.ItemHeight = 12;
            BottomListBox.Location = new System.Drawing.Point(5, 343);
            BottomListBox.Name = "BottomListBox";
            BottomListBox.ScrollAlwaysVisible = true;
            BottomListBox.Size = new System.Drawing.Size(746, 182);
            BottomListBox.TabIndex = 7;
          
            TopListBox.Parent = this.tabPage2;
            MiddleListBox.Parent = this.tabPage2;
            BottomListBox.Parent = this.tabPage2;
            this.tabPage2.Parent = this.tabControl1;
          
        }
 
 
        #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>
        /// 根据卡机数目初始化客户端卡机处于“断开状态”图片和卡机编号
        ///</summary>
        ///<param name="MachineCount"> 卡机数目 </param>
        public void InitMachineImage(int MachineCount)
        {
            PictureBoxArray = new PictureBox[MachineCount + 1];
            LabelArray = new Label[MachineCount + 1];
            for ( int i = 1; i <= MachineCount; i++)
            {
                PictureBoxArray[i] = new PictureBox();
                PictureBoxArray[i].Parent = this.ListViewImageConnectingStatus;
                // 获得客户端卡机断开与服务连接的“断开状态”图片
                PictureBoxArray[i].Image = this.imageList1.Images[0];
                PictureBoxArray[i].Left = 2 + 50 * (i - 1);
                PictureBoxArray[i].Top = 3;
                PictureBoxArray[i].SizeMode = PictureBoxSizeMode.AutoSize;
 
                PictureBoxArray[i].Visible = true;
                LabelArray[i] = new Label();
                LabelArray[i].Parent = this.ListViewImageConnectingStatus;
                LabelArray[i].Text = (i).ToString() + " 号" ;
                LabelArray[i].ForeColor = Color.Blue;
                LabelArray[i].Left = 2 + (i - 1) * 50;
                LabelArray[i].Top = 36;
                LabelArray[i].Visible = true;
                LabelArray[i].AutoSize = true;
 
            }
        }
              
        ///<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 CrcTableIndex = 0;
            byte CrcH8bit = 0x00, CrcL8bit = 0x00;
            for (int 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();
        }
 
        public static IPAddress GetServerIP()
        {
            IPHostEntry ieh = Dns.GetHostEntry(Dns.GetHostName());// Dns.GetHostByName(Dns.GetHostName();
            return ieh.AddressList[0];
        }
 
 
        public CardMachineCollection CardMachineList = new CardMachineCollection();
        ///<summary>
        /// 当服务器Socket实例_ServerSocket[它是SocketOfNewlyConnection赋给的值]收到的字节长度大于42个字节
        /// 并且OnReceiveData事件非null值时,触发事件要执行的方法CardMachine_OnReceiveData()
        ///</summary>
        ///<param name="sender"> 当前类的实例 </param>
        ///<param name="ReceiveString"> 服务器接收到的字符串(由服务器接收到的字节转变而来) </param>
        ///<param name="ReceiveStringLength"> 服务器接收到的字符串长度 </param>
        ///<param name="ReceiveBytes"> 服务器接收到的字节 </param>
        private void CardMachine_OnReceiveData(object sender, string ServerReceivedString, int ServerReceivedStringLength, byte[] ServerReceivedBytes)
        {
            try
            {
                string CardNo = string.Empty;
                string MachineNo = string.Empty;
                string ReadHeadNo = string.Empty;
                string SendToClientString = string.Empty;
                string EmpNo = string.Empty;
                string EmpName = string.Empty;
                string CardPassingState = string.Empty;
                string PassingTime = string.Empty;
                string PassingStateInfo = string.Empty;
 
                if (ServerReceivedString.IndexOf("<EOF>") > -1)
                {
                    (sender as CardMachine).Close();
                }
               
                if (ServerReceivedBytes[0] == 0x03 && (ServerReceivedStringLength == 43))
                {
                    // 从第0位到第42位(长度为43)这段字符串中截取第19位20位21位22位23位24位25位和第26位表示卡号的字串
                    CardNo = Convert.ToInt32(ServerReceivedString.Substring(19, 8), 16).ToString();
                    // 卡号不足10位左边补0,直到满足10位退出循环
                    while (CardNo.Length < 10)
                    {
                        CardNo = "0" + CardNo;
                    }
                    // 从第0位到第42位(长度为43)这段字符串中截取第1位和第2位表示卡机编号的字串
                    MachineNo = ServerReceivedString.Substring(1, 2);
                    // 从第0位到第42位(长度为43)这段字符串中截取第5位和第6位表示卡机读头编号的字串
                    ReadHeadNo = ServerReceivedString.Substring(5, 2);
                }
 
                if ( !string.IsNullOrEmpty(CardNo))
                {
                    if ((sender as CardMachine).SqlConn.State != ConnectionState.Open)
                    {
                        (sender as CardMachine).SqlConn.Open();
                    }
                    (sender as CardMachine).SqlComm.Parameters["@CardNo"].Value = CardNo;
                    (sender as CardMachine).SqlComm.Parameters["@MachineNo"].Value = MachineNo;
                    (sender as CardMachine).SqlComm.Parameters["@ReadHeadNo"].Value = Convert.ToInt32(ReadHeadNo);
 
                    (sender as CardMachine).SqlComm.ExecuteNonQuery();
                    EmpNo = (sender as CardMachine).SqlComm.Parameters["@EmpNo"].Value.ToString();
                    EmpName = (sender as CardMachine).SqlComm.Parameters["@EmpName"].Value.ToString();
                    CardPassingState = (sender as CardMachine).SqlComm.Parameters["@CardPassingState"].Value.ToString();
                    PassingTime = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss");
 
                    switch (CardPassingState)
                    {
                        case "0": PassingStateInfo = " 正常通行" ; break;
                        case "1": PassingStateInfo = " 无效卡号" ; break;
                        case "2": PassingStateInfo = " 未到或已过就餐时间" ; break;
                        case "3": PassingStateInfo = " 无设置就餐时段" ; break;
 
                    }
 
                    // 非正常通行时
                    if (CardPassingState != "0")
                    {
                        // 发送到客户端卡机的字符串(卡机读头编号固定为04)
                        SendToClientString = Convert.ToChar(0x01) + MachineNo + "JA" + "04" + Convert.ToChar(0x02);
                        // 将字符串转换成字节数组,以获得16进制CRC校验码
                        byte[] SendToClientBytes = System.Text.Encoding.Default.GetBytes(SendToClientString);
                        // 信息码+16进制CRC校验码+换行符
                        SendToClientString = SendToClientString + HexCrcCode(SendToClientBytes, 8) + Convert.ToChar(0x0D);
                        // 将字符串转换成字节数组
                        byte[] SendingToClientBytes = System.Text.Encoding.Default.GetBytes(SendToClientString);
                        // 将字节数组发送到客户端的卡机
                        (sender as CardMachine).SavedSocketOfNewlyConnected.Send(SendingToClientBytes);
                    }
                    else
                    {
                        // 发送到客户端卡机的字符串(读头编号是客户端卡机发送过来的43位字符串中包含的)
                        SendToClientString = Convert.ToChar(0x01) + MachineNo + "JA" + ReadHeadNo + Convert.ToChar(0x02);
                        // 将字符串转换成字节数组,以获得16进制CRC校验码
                        byte[] SendToClientBytes = System.Text.Encoding.Default.GetBytes(SendToClientString);
                        // 信息码+16进制CRC校验码+换行符
                        SendToClientString = SendToClientString + HexCrcCode(SendToClientBytes, 8) + Convert.ToChar(0x0D);
                        // 将字符串转换成字节数组
                        byte[] SendingToClientBytes = System.Text.Encoding.Default.GetBytes(SendToClientString);
                        // 将字节数组发送到客户端的卡机
                        (sender as CardMachine).SavedSocketOfNewlyConnected.Send(SendingToClientBytes);
                    }
 
                    ListViewItem listViewItem = this.PassedRecordlistView.Items.Insert(0, EmpNo);
                    listViewItem.SubItems.AddRange(new string[] { EmpName, PassingTime, CardNo, PassingStateInfo, MachineNo, ReadHeadNo });
 
                }
            }
            catch (System.Exception ex)
            {
                //MiddleListBox 中显示CardMachine_OnReceiveData方法出现错误的时间
                MiddleListBox.Items.Add(DateTime.Now.ToString() + " : CardMachine_OnReceiveData方法中的错误    " + ex.ToString());
                //MiddleListBox 中显示的数据超过2000条,就删除索引为 1 的那条记录
                if (MiddleListBox.Items.Count > 2000) { MiddleListBox.Items.RemoveAt(1); }
            }
            // PassedRecordlistView 中显示的数据超过500条,就删除索引为 1 的那条记录
            if (this.PassedRecordlistView.Items.Count >= 500)
            PassedRecordlistView.Items.RemoveAt(1);
        }
      
     
        ///<summary>
        /// 通过MainForm_Load事件中创建的线程启动服务器端Socket监听
        ///</summary>
        private void BeginServerSocketListening()
        {
            byte[] bytes = new byte[1024];
            int i;
            string ClientMachineIP;
            try
            {
                // 读取服务器IP地址
                IPAddress ServerIp = GetServerIP();
                // 指定双方在8000端口上通讯,也可以把8000写到配置文件中
                IPEndPoint iep = new IPEndPoint(ServerIp, 8000);
                ServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
 
                byte[] byteMessage = new byte[100];
                ServerSocket.Bind(iep);
                ServerSocket.Listen(0);
                // “永真循环”,在FormClosing事件中重新设置IsServerSocketRunning
                // 为False,以退出这个“死循环”,退出服务器Socket处于等待连接的状态
                while (IsServerSocketRunning)
                {
                    this.Text = " 卡机服务器IP[ " + iep.ToString() + " ] 正在监听客户端卡机的连线请求 ‥‥‥" ;
 
                    // Accept() 方法执行完毕,目的是等待客户端Socket对象的连接请求
                    // 当客户端Socket执行Send(byte[])方法时,该行代码才继续顺序向
                    // 下执行,否则就一直处于等待被连接的状态,代码执行暂停在该行;
                    // 返回值是为新建连接创建新的 Socket对象,它包含了本地终结点和
                    // 远程终结点,还包含了Connected属性是否已连接到远程主机(客户
                    // 端卡机)和Available 属性(已经从网络接收且可供读取的数据量)等等
                    // 方法和属性信息。
                    SocketOfNewlyConnection = ServerSocket.Accept();
                    // 新建一个卡机对象实例,将已创建的新 Socket 对象包装进来
                    CardMachine cardMachine = new CardMachine(SocketOfNewlyConnection);
                    // 实例化委托类型的事件OnReceiveData,当服务器Socket实例_ServerSocket[它是SocketOfNewlyConnection赋给的值]收到的字节
                    // 长度大于42个字节并且OnReceiveData事件非null值时,触发事件要执行的方法CardMachine_OnReceiveData()
                    cardMachine.OnReceiveData += new CardMachine.DegReceiveData(CardMachine_OnReceiveData);
                    // 获取远程终结点(客户端卡机的IP和端口)中的IP地址
                    ClientMachineIP = ((IPEndPoint)(SocketOfNewlyConnection.RemoteEndPoint)).Address.ToString();
                    // 遍历配置文件(app.config)中用户输入的卡机数目
                    for (i = 0; i < CardMachineList.Count; i++)
                    {
                        // 如果保存在卡机集合列表中存在与从远程终结点中获得的IP地址
                        if (CardMachineList[i].ClientMachineIpAddress == ClientMachineIP)
                        {   // 那么就用最新的卡机对象取代过去的卡机对象;
                            CardMachineList[i] = cardMachine;
                            // 并将连接状态的图片设置为“已连接上”的图片;
                            PictureBoxArray[i + 1].Image = ConnectedPictureBox.Image;
                            // 设置客户端卡机的编号
                            cardMachine.ClientMachineNo = i + 1;
                        }
                    }
                    //MiddleListBox 中显示一空行
                    MiddleListBox.Items.Add("");
                    //MiddleListBox 中显示的数据超过2000条,就删除索引为 1 的那条记录
                    if (MiddleListBox.Items.Count > 2000) { MiddleListBox.Items.RemoveAt(1); }
                    //MiddleListBox 中显示数据来自那台卡机(IP地址和端口)的数据
                    MiddleListBox.Items.Add(DateTime.Now.ToString() + " : 服务器已收到来自客户端[ " + SocketOfNewlyConnection.RemoteEndPoint.ToString() + " ] 发过来的数据" );
                    //MiddleListBox 中显示的数据超过2000条,就删除索引为 1 的那条记录
                    if (MiddleListBox.Items.Count > 2000) { MiddleListBox.Items.RemoveAt(1); }
 
                }
            }
            catch (System.Exception ex)
            {
                //MiddleListBox 中显示BeginServerSocketListening方法中出现错误的时间
                MiddleListBox.Items.Add(DateTime.Now.ToString() + " : BeginServerSocketListening方法中的错误   " + ex.ToString());
                //MiddleListBox 中显示的数据超过2000条,就删除索引为 1 的那条记录
                if (MiddleListBox.Items.Count > 2000) { MiddleListBox.Items.RemoveAt(1); }
            }
        }
        private void MainForm_Load(object sender, EventArgs e)
        {
            int i, j;
            //MiddleListBox 中显示服务器启动时间
            MiddleListBox.Items.Add(DateTime.Now.ToString() + " : 服务器已经启动 " );
            // 获得客户端卡机连接到服务状态下的“连接状态”图片
            ConnectedPictureBox = new PictureBox();
            ConnectedPictureBox.Image = this.imageList1.Images[1];
            // 获得客户端卡机断开与服务连接的“断开状态”图片
            DisconnectedPictureBox = new PictureBox();
            DisconnectedPictureBox.Image = this.imageList1.Images[0];
            // 读取配置文件(app.config)中用户输入的卡机数目
            MachineCount = Convert.ToInt32(ConfigurationManager.AppSettings["MachineCount"]);
            for (i = 0; i < MachineCount; i++)
            {
                // 新建一个卡机对象实例
               CardMachine cardMachine = new CardMachine(null);
                // 加 1 是因为卡机编号从1开始编号
                j = i + 1;
                // 卡机对象实例保存到卡机集合列表中
                CardMachineList.Add(cardMachine);
                // 读取配置文件(app.config)中用户输入的卡机编号对应的IP地址保存到卡机集合列表中
                CardMachineList[i].ClientMachineIpAddress = ConfigurationManager.AppSettings["MachineNo" + j.ToString()];
                // 读取配置文件(app.config)中用户输入的卡机编号保存到卡机集合列表中
                CardMachineList[i].ClientMachineNo = j;
            }
            // 根据卡机数目初始化客户端卡机处于“断开状态”图片和卡机编号
            InitMachineImage(MachineCount);
            try
            {
                // 创建一个线程用来准备启动服务端的Socket监听
                ThreadOfStartServerSocketListening = new Thread(new ThreadStart(BeginServerSocketListening));
                // 正式启动服务端的Socket监听
                ThreadOfStartServerSocketListening.Start();
            }
            catch (Exception ex)
            {
                //MiddleListBox 中显示MainForm_Load事件中的错误
                MiddleListBox.Items.Add(DateTime.Now.ToString() + " : MainForm_Load事件中的错误 " + ex.ToString());
                //MiddleListBox 中显示的数据超过2000条,就删除索引为 1 的那条记录
                if (MiddleListBox.Items.Count > 2000) { MiddleListBox.Items.RemoveAt(1); }
            }
 
        }
 
        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            // 结束“永真循环”退出服务器Socket处于等待连接的状态
            IsServerSocketRunning = false;
            for (int i = 0; i < this.CardMachineList.Count; i++)
            {
                this.CardMachineList[i].Close();
            }
        }
 
        private void timer1_Tick(object sender, System.EventArgs e)
        {
            try
            {
                ServerPromgramRunningSeconds++;
                // 每隔60秒报告一次每台卡机的连接状态
                if (ServerPromgramRunningSeconds % 60 == 0)
                {
                    // 重新记时,避免数据过大占用内存
                    ServerPromgramRunningSeconds = 0;
                    //TopListBox 中显示一空行
                    TopListBox.Items.Add("");
                    //TopListBox 中显示的数据超过2000条,就删除索引为 1 的那条记录
                    if (TopListBox.Items.Count > 2000) { TopListBox.Items.RemoveAt(1); }
                    for (int i = 0; i < CardMachineList.Count; i++)
                    {
                        //TopListBox 中显示卡机IP和连接状态
                        TopListBox.Items.Add(DateTime.Now.ToString() + " : [ " + CardMachineList[i].ClientMachineNo.ToString() +
                                           " ] 号机IP[ " + CardMachineList[i].ClientMachineIpAddress +
                                           " ] 连接状态[ " + CardMachineList[i].ClientIsConnected.ToString() + " ]");
                        //TopListBox 中显示的数据超过2000条,就删除索引为 1 的那条记录
                        if (TopListBox.Items.Count > 2000) { TopListBox.Items.RemoveAt(1); }
                    }
                    //MiddleListBox 中显示一空行
                    MiddleListBox.Items.Add("");
                    //MiddleListBox 中显示的数据超过2000条,就删除索引为 1 的那条记录
                    if (MiddleListBox.Items.Count > 2000) { MiddleListBox.Items.RemoveAt(1); }
                    //BottomListBox 中显示一空行
                    BottomListBox.Items.Add("");
                    //BottomListBox 中显示的数据超过2000条,就删除索引为 1 的那条记录
                    if (BottomListBox.Items.Count > 2000) { BottomListBox.Items.RemoveAt(1); }
                }
 
                for (int i = 0; i < CardMachineList.Count; i++)
                {
                    // 每台卡机每隔1秒钟ClientConnectedLifeTime会自动加上1秒(Timer事件每隔1秒触发一次)
                    CardMachineList[i].ClientConnectedLifeTime += 1;
                    // 如果某一台卡机连接时间超过70秒时
                    if (CardMachineList[i].ClientConnectedLifeTime > 70)
                    {
                        //(1) 将该台卡机连接时间清0
                        CardMachineList[i].ClientConnectedLifeTime = 0;
                        //(2) 如果该台卡机还处在“已连接上”上的状态
                        if (CardMachineList[i].ClientIsConnected == true)
                        {
                            //(a) 将该卡机已连接状态的图片设置为断开状态的图片
                            PictureBoxArray[CardMachineList[i].ClientMachineNo].Image = DisconnectedPictureBox.Image;
                            //(b) 如果该卡机已与服务器通讯了
                            if (CardMachineList[i].SavedSocketOfNewlyConnected != null)
                            {
                                //(i)   设置ServerSocketIsActive为非活动状态;
                                //(ii)  禁用SavedSocketOfNewlyConnected上的发送和接收并释放所有关联的资源;
                                //(iii) 结束ThreadOfServerIsWaitingForClientData线程的执行。
                                CardMachineList[i].Close();
                            }
                            //(c) 将该卡机的连接属性设置为断开连接
                            CardMachineList[i].ClientIsConnected = false;
                            //(d) 将该卡机设置为非活动状态.
                            CardMachineList[i].ServerSocketIsActive = false;
                        }
                        //BottomListBox 中显示一空行
                        BottomListBox.Items.Add("");
                        //BottomListBox 中显示的数据超过2000条,就删除索引为 1 的那条记录
                        if (BottomListBox.Items.Count > 2000) { BottomListBox.Items.RemoveAt(1); }
                        for (int j = 0; j < CardMachineList.Count; j++)
                        {
                            //(4) 报告每台卡机的连接状态
                            BottomListBox.Items.Add(DateTime.Now.ToString() + " : [ " + CardMachineList[j].ClientMachineNo.ToString() +
                                         " ] 号机IP[ " + CardMachineList[j].ClientMachineIpAddress +
                                         " ] 连接状态[ " + CardMachineList[j].ClientIsConnected.ToString()+" ]");
                            //BottomListBox 中显示的数据超过2000条,就删除索引为 1 的那条记录
                            if (BottomListBox.Items.Count > 2000) { BottomListBox.Items.RemoveAt(1); }
                        }
                    }
                }
            }
            catch (System.Exception ex)
            {
                //MiddleListBox 中显示timer1_Tick 事件中出现错误的时间
                MiddleListBox.Items.Add(DateTime.Now.ToString() + " : timer1_Tick 事件中的错误 " + ex.ToString());
                //MiddleListBox 中显示的数据超过2000条,就删除索引为 1 的那条记录
                if (MiddleListBox.Items.Count > 2000) { MiddleListBox.Items.RemoveAt(1); }
            }
 
        }
 
    }
}
 
 
 
 
 
 
 
 
 
2.MainForm.Designer.cs:
 
namespace Server
{
    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
            {
                ServerSocket.Shutdown(System.Net.Sockets.SocketShutdown.Both);
                ServerSocket.Close();
                ThreadOfStartServerSocketListening.Abort();
            }
            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();
            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
            this.tabControl1 = new System.Windows.Forms.TabControl();
            this.tabPage1 = new System.Windows.Forms.TabPage();
            this.PassedRecordlistView = new System.Windows.Forms.ListView();
            this.columnHeader1 = new System.Windows.Forms.ColumnHeader();
            this.columnHeader2 = new System.Windows.Forms.ColumnHeader();
            this.columnHeader3 = new System.Windows.Forms.ColumnHeader();
            this.columnHeader4 = new System.Windows.Forms.ColumnHeader();
            this.columnHeader5 = new System.Windows.Forms.ColumnHeader();
            this.columnHeader6 = new System.Windows.Forms.ColumnHeader();
            this.columnHeader7 = new System.Windows.Forms.ColumnHeader();
            this.tabPage2 = new System.Windows.Forms.TabPage();
            this.ListViewImageConnectingStatus = new System.Windows.Forms.ListView();
            this.timer1 = new System.Windows.Forms.Timer(this.components);
            this.imageList1 = new System.Windows.Forms.ImageList(this.components);
            this.tabControl1.SuspendLayout();
            this.tabPage1.SuspendLayout();
            this.SuspendLayout();
            //
            // tabControl1
            //
            this.tabControl1.Controls.Add(this.tabPage1);
            this.tabControl1.Controls.Add(this.tabPage2);
            this.tabControl1.Dock = System.Windows.Forms.DockStyle.Fill;
            this.tabControl1.Location = new System.Drawing.Point(0, 55);
            this.tabControl1.Name = "tabControl1";
            this.tabControl1.SelectedIndex = 0;
            this.tabControl1.Size = new System.Drawing.Size(762, 530);
            this.tabControl1.TabIndex = 0;
            //
            // tabPage1
            //
            this.tabPage1.Controls.Add(this.PassedRecordlistView);
            this.tabPage1.Location = new System.Drawing.Point(4, 21);
            this.tabPage1.Name = "tabPage1";
            this.tabPage1.Padding = new System.Windows.Forms.Padding(3);
            this.tabPage1.Size = new System.Drawing.Size(754, 505);
            this.tabPage1.TabIndex = 0;
            this.tabPage1.Text = " 通行记录" ;
            this.tabPage1.UseVisualStyleBackColor = true;
            //
            // PassedRecordlistView
            //
            this.PassedRecordlistView.AllowColumnReorder = true;
            this.PassedRecordlistView.BackColor = System.Drawing.Color.Black;
            this.PassedRecordlistView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
            this.columnHeader1,
            this.columnHeader2,
            this.columnHeader3,
            this.columnHeader4,
            this.columnHeader5,
            this.columnHeader6,
            this.columnHeader7});
            this.PassedRecordlistView.Dock = System.Windows.Forms.DockStyle.Fill;
            this.PassedRecordlistView.Font = new System.Drawing.Font("PMingLiU", 9F);
            this.PassedRecordlistView.ForeColor = System.Drawing.Color.Lime;
            this.PassedRecordlistView.FullRowSelect = true;
            this.PassedRecordlistView.Location = new System.Drawing.Point(3, 3);
            this.PassedRecordlistView.Name = "PassedRecordlistView";
            this.PassedRecordlistView.Size = new System.Drawing.Size(748, 499);
            this.PassedRecordlistView.TabIndex = 0;
            this.PassedRecordlistView.UseCompatibleStateImageBehavior = false;
            this.PassedRecordlistView.View = System.Windows.Forms.View.Details;
            //
            // columnHeader1
            //
            this.columnHeader1.Text = " 工号" ;
            this.columnHeader1.Width = 80;
            //
            // columnHeader2
            //
            this.columnHeader2.Text = " 姓名" ;
            this.columnHeader2.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
            this.columnHeader2.Width = 80;
            //
            // columnHeader3
            //
            this.columnHeader3.Text = " 时间" ;
            this.columnHeader3.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
            this.columnHeader3.Width = 133;
            //
            // columnHeader4
            //
            this.columnHeader4.Text = " 卡号" ;
            this.columnHeader4.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
            this.columnHeader4.Width = 91;
            //
            // columnHeader5
            //
            this.columnHeader5.Text = " 状态" ;
            this.columnHeader5.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
            this.columnHeader5.Width = 127;
            //
            // columnHeader6
            //
            this.columnHeader6.Text = " 机器号" ;
            this.columnHeader6.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
            //
            // columnHeader7
            //
            this.columnHeader7.Text = " 进出" ;
            this.columnHeader7.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
            //
            // tabPage2
            //
            this.tabPage2.Location = new System.Drawing.Point(4, 21);
            this.tabPage2.Name = "tabPage2";
            this.tabPage2.Padding = new System.Windows.Forms.Padding(3);
            this.tabPage2.Size = new System.Drawing.Size(754, 505);
            this.tabPage2.TabIndex = 1;
            this.tabPage2.Text = " 终端设备运行信息" ;
            this.tabPage2.UseVisualStyleBackColor = true;
            //
            // ListViewImageConnectingStatus
            //
            this.ListViewImageConnectingStatus.BackColor = System.Drawing.SystemColors.Control;
            this.ListViewImageConnectingStatus.Dock = System.Windows.Forms.DockStyle.Top;
            this.ListViewImageConnectingStatus.Location = new System.Drawing.Point(0, 0);
            this.ListViewImageConnectingStatus.Name = "ListViewImageConnectingStatus";
            this.ListViewImageConnectingStatus.Size = new System.Drawing.Size(762, 55);
            this.ListViewImageConnectingStatus.TabIndex = 1;
            this.ListViewImageConnectingStatus.UseCompatibleStateImageBehavior = false;
            //
            // timer1
            //
            this.timer1.Enabled = true;
            this.timer1.Interval = 1000;
            this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
            //
            // imageList1
            //
            this.imageList1.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imageList1.ImageStream")));
            this.imageList1.TransparentColor = System.Drawing.Color.Transparent;
            this.imageList1.Images.SetKeyName(0, "");
            this.imageList1.Images.SetKeyName(1, "");
            //
            // MainForm
            //
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(762, 585);
            this.Controls.Add(this.tabControl1);
            this.Controls.Add(this.ListViewImageConnectingStatus);
            this.Name = "MainForm";
            this.Text = " 智能通道系统" ;
            this.Load += new System.EventHandler(this.MainForm_Load);
            this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MainForm_FormClosing);
            this.tabControl1.ResumeLayout(false);
            this.tabPage1.ResumeLayout(false);
            this.ResumeLayout(false);
 
        }
 
        #endregion
 
        private System.Windows.Forms.TabControl tabControl1;
        private System.Windows.Forms.TabPage tabPage1;
        private System.Windows.Forms.ListView PassedRecordlistView;
        private System.Windows.Forms.TabPage tabPage2;
        private System.Windows.Forms.ListView ListViewImageConnectingStatus;
        private System.Windows.Forms.Timer timer1;
        private System.Windows.Forms.ImageList imageList1;
        private System.Windows.Forms.ColumnHeader columnHeader1;
        private System.Windows.Forms.ColumnHeader columnHeader2;
        private System.Windows.Forms.ColumnHeader columnHeader3;
        private System.Windows.Forms.ColumnHeader columnHeader4;
        private System.Windows.Forms.ColumnHeader columnHeader5;
        private System.Windows.Forms.ColumnHeader columnHeader6;
        private System.Windows.Forms.ColumnHeader columnHeader7;
    }
}
 
 
 
3.CardMachineCollection.cs:
 
//***********************************************************************************************
//    作者 :郑紫至
//  创建日期:2008-03-14
//  邮件地址:zhengzizhi@mail.china.com
//  博客地址:http://hi.csdn.net/zhengzizhi
//  备注说明:欢迎大家转载我的博客内容,代码版权归本人所有,请保留此信息。
//***********************************************************************************************
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
 
namespace Server
{
    public class CardMachineCollection : CollectionBase
    {
        public CardMachine this[int index]
        {
            get { return ((CardMachine)List[index]); }
            set { List[index] = value; }
        }
 
        public int Add(CardMachine value)
        {
            return (List.Add(value));
        }
 
 
        public void Remove(CardMachine value)
        {
            List.Remove(value);
        }
 
 
    }
}
 
 
 
4.CardMachine.cs
 
//******************************************************************************************
//    作者 :郑紫至
//  创建日期:2008-03-14
//  邮件地址:zhengzizhi@mail.china.com
//  博客地址:http://hi.csdn.net/zhengzizhi
//  备注说明:欢迎大家转载我的博客内容,代码版权归本人所有,请保留此信息。
//******************************************************************************************
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Data.SqlClient;
using System.Threading;
using System.Configuration;
using System.Data;
 
namespace Server
{
    public class CardMachine
    {
        ///<summary>
        /// 保存由服务器Accecpt方法返回的一个新创建的Socket对象
        ///</summary>
        public Socket SavedSocketOfNewlyConnected=null;
        public Thread ThreadOfServerIsWaitingForClientData;
        public SqlConnection SqlConn=null;
        public SqlCommand SqlComm=null;
        ///<summary>
        /// ServerSocketIsActive 默认为活动状态
        ///</summary>
        public bool ServerSocketIsActive = true;
        ///<summary>
        /// 委托类型的事件
        ///</summary>
        public event DegReceiveData OnReceiveData;
        public delegate void DegReceiveData(object sender, string ReceiveString, int ReceiveStringLength, byte[] ReceiveBytes);
       
        private int _ClientConnectedLifeTime = 0;
        ///<summary>
        /// 卡机连接服务器的秒数( 默认为0 )
        ///</summary>
        public int ClientConnectedLifeTime
        {
            get { return _ClientConnectedLifeTime; }
            set { _ClientConnectedLifeTime = value; }
        }
 
        private int _ClientMachineNo = 0;
        ///<summary>
        /// 卡机编号( 默认为0 )
        ///</summary>
        public int ClientMachineNo
        {
            get { return _ClientMachineNo; }
            set { _ClientMachineNo = value; }
        }
 
        private bool _ClientIsConnected = false;
        ///<summary>
        /// 卡机连接状态( 默认为断开 )
        ///</summary>
        public bool ClientIsConnected
        {
            get { return _ClientIsConnected; }
            set { _ClientIsConnected = value; }
        }
 
        private string _ClientMachineIpAddress = string.Empty;
        ///<summary>
        /// 卡机IP地址
        ///</summary>
        public string ClientMachineIpAddress
        {
            get { return _ClientMachineIpAddress; }
            set { _ClientMachineIpAddress = value; }
        }
 
        ///<summary>
        /// 在已连接数据库的状态下,建立一个操作数据库存储过程的SqlCommand对象实例SqlComm,并定义存储过程中
        /// 要使用的参数类型和长度,最后线程启动ServerIsWaitingForClientData()方法接收来自客户端发过来的字节数据
        ///</summary>
        ///<param name="SocketOfNewlyConnected"> 服务器Accecpt方法返回的新建Socket对象 </param>
        public CardMachine(Socket SocketOfNewlyConnected)
        {
            if (SocketOfNewlyConnected != null)// 在执行窗体Load事件的时候会传null值过来,其它情况都是非null值
            {
                SqlConn = new SqlConnection(ConfigurationManager.AppSettings["ConnectionString"]);
                SqlConn.Open();
                SqlComm = new SqlCommand("dbo.[CheckDiningEmpInfoByCardNo]", SqlConn);
                SqlComm.CommandType = System.Data.CommandType.StoredProcedure;
                SqlComm.Connection = SqlConn;
                SqlComm.Parameters.Add(new SqlParameter("@RETURN_VALUE", SqlDbType.Int, 4,
                                   ParameterDirection.ReturnValue, false, (System.Byte)(0),
                                   (System.Byte)(0), "",DataRowVersion.Current, null));
                SqlComm.Parameters.Add(new SqlParameter("@CardNo", SqlDbType.VarChar, 10));
                SqlComm.Parameters.Add(new SqlParameter("@MachineNo", SqlDbType.VarChar, 5));
                SqlComm.Parameters.Add(new SqlParameter("@ReadHeadNo", SqlDbType.Int, 4));
                SqlComm.Parameters.Add(new SqlParameter("@EmpNo", SqlDbType.VarChar, 8,
                                   ParameterDirection.Output, false, (System.Byte)(0),
                                   (System.Byte)(0),"", DataRowVersion.Current, null));
                SqlComm.Parameters.Add(new SqlParameter("@EmpName", SqlDbType.NVarChar, 20,
                                   ParameterDirection.Output, false, (System.Byte)(0),
                                   (System.Byte)(0),"", DataRowVersion.Current, null));
                SqlComm.Parameters.Add(new SqlParameter("@CardPassingState", SqlDbType.Int, 4,
                                   ParameterDirection.Output, false, (System.Byte)(0),
                                   (System.Byte)(0),"", DataRowVersion.Current, null));
                // 设置卡机连接服务器的状态为“已连接上”.
                ClientIsConnected = true;
                // 获取远程终结点(客户端卡机的IP和端口)中的IP地址
                ClientMachineIpAddress =((IPEndPoint)(SocketOfNewlyConnected.RemoteEndPoint)).Address.ToString();
                // 保存服务器Accecpt方法返回的新建Socket对象到SavedSocketOfNewlyConnected变量中
                SavedSocketOfNewlyConnected = SocketOfNewlyConnected;
                // 创建一个新线程准备执行ServerIsWaitingForClientData()方法
                ThreadOfServerIsWaitingForClientData = new Thread(new ThreadStart(ServerIsWaitingForClientData));
                // 启动线程,开始执行ServerIsWaitingForClientData()方法
                ThreadOfServerIsWaitingForClientData.Start();
            }
        }
 
        ///<summary>
        ///
        ///</summary>
        public void ServerIsWaitingForClientData()
        {
            // 保存客户端发到服务器的字节数组
            byte[] BytesOfClientToServer = new byte[1024];
            int MachineNo, ServerReceivedFromClientLengthOfBytes = 0;
            try
            {
                // SavedSocketOfNewlyConnected 会在MainForm的timer1_Tick事件中每隔70秒释放一次
                while (ServerSocketIsActive && SavedSocketOfNewlyConnected != null)
                {
                    // 使用SavedSocketOfNewlyConnected对象接收来自客户端Socket对象发过来的字节数据并
                    // 且将接收方法返回的字节长度数据保存到ServerReceivedFromClientLengthOfBytes变量中
                    ServerReceivedFromClientLengthOfBytes = SavedSocketOfNewlyConnected.Receive(BytesOfClientToServer);
                    // 定义一个将接收到的字节转换成字符串的变量
                    string ServerReceivedFromClientString = string.Empty ;
                    // 将字节转换成字符串
                    ServerReceivedFromClientString += Encoding.ASCII.GetString(
                                                    BytesOfClientToServer, 0, ServerReceivedFromClientLengthOfBytes);
                    //
                    if (ServerReceivedFromClientString.Length == 11)
                    {
                        // 从第0位到第10位(长度为11)这段字符串中截取第1位和第2位表示卡机编号的字串
                        MachineNo = Convert.ToInt32(ServerReceivedFromClientString.Substring(1, 2));
                        // MiddleListBox 中显示一空行
                        MainForm.MiddleListBox.Items.Add("");
                        // MiddleListBox 中显示的数据超过2000条,就删除索引为 1 的那条记录
                        if (MainForm.MiddleListBox.Items.Count > 2000) { MainForm.MiddleListBox.Items.RemoveAt(1); };
                        // MiddleListBox 中显示当前卡机完成一次完整的通讯结束信号
                        MainForm.MiddleListBox.Items.Add(DateTime.Now.ToString() + " : 服务器已收到[ " +
                                                       MachineNo.ToString() + " ] 号卡机传回本次完整通讯结束的<EOF>信号" );
                        // MiddleListBox 中显示的数据超过2000条,就删除索引为 1 的那条记录
                        if (MainForm.MiddleListBox.Items.Count > 2000) { MainForm.MiddleListBox.Items.RemoveAt(1); };
                        // 将当前卡机编号的连接状态图片设置为“已连接上”的图片;
                        MainForm.PictureBoxArray[MachineNo].Image = MainForm.ConnectedPictureBox.Image;
                        ClientConnectedLifeTime = 0;
                    }
                    if (ServerReceivedFromClientString.IndexOf("<EOF>") > -1)
                    {
                        break;// 如果接收的字符串包含了“<EOF>”标记,退出以结束本次通讯
                    }
                    // 接收字节长度大于 42 表示一次完整通讯客户端发过来真正有用的数据
                    if ((ServerReceivedFromClientLengthOfBytes > 42) && (OnReceiveData != null))
                    //
                    { OnReceiveData(this, ServerReceivedFromClientString, ServerReceivedFromClientLengthOfBytes, BytesOfClientToServer); }
                }
            }
            catch (Exception ex)
            {
                // MiddleListBox 中显示ServerIsWaitingForClientData方法出现错误的时间
                MainForm.MiddleListBox.Items.Add(DateTime.Now.ToString() +
                    " : ServerIsWaitingForClientData方法中的错误 " + ex.ToString());
                // MiddleListBox 中显示的数据超过2000条,就删除索引为 1 的那条记录
                if (MainForm.MiddleListBox.Items.Count > 2000) { MainForm.MiddleListBox.Items.RemoveAt(1); };
            }
        }
        ///<summary>
        /// 设置ServerSocketIsActive为非活动状态;
        /// 禁用SavedSocketOfNewlyConnected上的发送和接收并释放所有关联的资源;
        /// 结束ThreadOfServerIsWaitingForClientData线程的执行。
        ///</summary>
        public void Close()
        {
            ServerSocketIsActive = false;
            try
            {
                if (SavedSocketOfNewlyConnected != null)
                {
                    //(i) 禁用SavedSocketOfNewlyConnected上的发送和接收
                    SavedSocketOfNewlyConnected.Shutdown(SocketShutdown.Both);
                    //(ii) 关闭 SavedSocketOfNewlyConnected连接并释放所有关联的资源
                    SavedSocketOfNewlyConnected.Close();
                    //(iii) 结束用来启动ServerIsWaitingForClientData()方法的线程
                    ThreadOfServerIsWaitingForClientData.Abort();
                }
            }
            catch
            { }
        }
          
 
       
       
 
    }
}
 
 
5. app.config
<? xml version = "1.0"encoding="utf-8" ?>
< configuration >
    < configSections >
    </ configSections >
    < connectionStrings >
        < add name = "Server.Properties.Settings.IRSConnectionString"
            connectionString = ""
            providerName = "System.Data.SqlClient" />
    </ connectionStrings >
 < appSettings >
    < add key = "ConnectionString"value="Data Source=VSNET2008/SQLEXPRESS;Initial Catalog=IRS;Integrated Security=True"/>
    < add key = "MachineCount"value="9"/>
    < add key = "MachineNo1"value="192.168.1.91"/>
    < add key = "MachineNo2"value="192.168.1.92"/>
    < add key = "MachineNo3"value="192.168.1.93"/>
    < add key = "MachineNo4"value="192.168.1.94"/>
    < add key = "MachineNo5"value="192.168.1.95"/>
    < add key = "MachineNo6"value="192.168.1.96"/>
    < add key = "MachineNo7"value="192.168.1.97"/>
    < add key = "MachineNo8"value="192.168.1.98"/>
    < add key = "MachineNo9"value="192.168.1.99"/>
 </ appSettings >
</ configuration >
 
6. Program
 
//***********************************************************************************************
//    作者 :郑紫至
//  创建日期:2008-03-14
//  邮件地址:zhengzizhi@mail.china.com
//  博客地址:http://hi.csdn.net/zhengzizhi
//  备注说明:欢迎大家转载我的博客内容,代码版权归本人所有,请保留此信息。
//***********************************************************************************************
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
 
namespace Server
{
    static class Program
    {
        ///<summary>
        /// The main entry point for the application.
        ///</summary>
        [STAThread]
        static void Main()
        {
            Control.CheckForIllegalCrossThreadCalls = false;
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new MainForm());
        }
    }
}
 
 
Server 项目所有代码全部发布完毕(包括自动生成的代码)

在整个方案中的结构如下图所显:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值