问题背景:在实现智能家居项目中,要实现服务器接受到zigbee模块采集到的信息,并且将该数据通过socket通信传输给客户端。

Socket 通信流程图 - rpf413 - rpf413的博客

以下是服务器客户端

//以下的using是自己添加的using System.IO.Ports;using System.Net;using System.Net.Sockets;using System.Threading;namespace NJGB智能家居系统V10{    public partial class Form1 : Form    {        Socket listener;        bool socketstart_or_stop = false;        Thread threadWatch = null;        Dictionary
 dict = new Dictionary
();        Dictionary
 dictThread = new Dictionary
();        private byte keting_dianshiji_kongzhi_or_xuexi, keting_jidinghe_kongzhi_or_xuexi,woshikongtiao_kongzhi_or_xuexi;        public Form1()        {            InitializeComponent();        }        private void Form1_Load(object sender, EventArgs e)        {            /*******************串口的初始操作*************/            string[] ports = SerialPort.GetPortNames();//定义一个字符串等于获取到的com名字            Array.Sort(ports);//给com口排序            comboBox_com.Items.AddRange(ports);//将com口添加到串口选择框            comboBox_com.SelectedIndex = comboBox_com.Items.Count > 0 ? 0 : -1;//让串口列表框第一行就显示com             //初始化SerialPort对象              comm.NewLine = "/r/n";            comm.RtsEnable = true;//根据实际情况吧。             comm.DataReceived += comm_DataReceived;            /***************获取ip地址并显示在ip地址框内***********************/            IPHostEntry host = Dns.GetHostEntry(Dns.GetHostName());//获取ip地址            foreach (IPAddress ip in host.AddressList)            {                textBox_IP.Text = ip.ToString();//ip地址显示在ip地址框内            }            /*****************设置程序初始状态,只有选择好com口后并打开,程序其他部分才可用*******/            groupBox_keting.Enabled = false;            groupBox_woshi.Enabled = false;            groupBox_chufang.Enabled = false;            groupBox_weishengjian.Enabled = false;            textBox_IP.Enabled = false;            this.button_Start_Server.Enabled = false;//启动服务器按钮不可用            this.button_Stop_Server.Enabled = false;//停止服务器按钮是灰色不可用            this.keting_dianshiji_kongzhi.Checked = true;            this.keting_dianshiji_xuexi.Checked = false;            this.keting_jidinghe_kongzhi.Checked = true;            this.keting_jidinghe_xuexi.Checked = false;            if (keting_dianshiji_kongzhi.Checked == true)                keting_dianshiji_kongzhi_or_xuexi = 0x6F;            if (keting_jidinghe_kongzhi.Checked == true)                keting_jidinghe_kongzhi_or_xuexi = 0x6F;        }                void comm_DataReceived(object sender, SerialDataReceivedEventArgs e)        {            if (comClosing) return;//如果正在关闭,忽略操作,直接返回,尽快的完成串口监听线程的一次循环             int index=0;            try            {                int n = comm.BytesToRead;//先记录下来,避免某种原因,人为的原因,操作几次之间时间长,缓存不一致                byte[] buf = new byte[n];//声明一个临时数组存储当前来的串口数据                comm.Read(buf, 0, n);//读取缓冲数据                builder.Clear();//清除字符串构造器的内容                //因为要访问ui资源,所以需要使用invoke方式同步ui。                this.Invoke((EventHandler)(delegate                {                    sockSend(buf);                    try                    {                        foreach (byte b in buf)                        {                            if (0x1A == b)                            {                                 /**********温度*******************************/                                if (buf[index + 1] == 0x60)//0x60是上传温度命令                                {                                    if (buf[index + 2] == 0x01)//1号终端就是客厅温度和灯模块                                    {                                        this.textBox_keting_wendu.Text = buf[index + 3].ToString() ;                                    }                                    if (buf[index + 2] == 0x02)//2号终端就是卧室温度和灯模块                                    {                                        this.textBox_woshi_wendu.Text = buf[index + 3].ToString();                                    }                                    if (buf[index + 2] == 0x04)//4号终端就是卫生间温度和灯模块                                    {                                        this.textBox_weishengjian_wendu.Text = buf[index + 3].ToString();                                    }                                }                                /*******************烟雾状态*************************/                                if (buf[index + 1] == 0x62)//0x62表示pc收到的数据是烟雾数据                                {                                     this.textBox_chufang_yanwu.Text = buf[index + 3].ToString();                                }                                /*************灯状态****************************/                                if (buf[index + 1] == 0x61)//上传灯状态命令                                {                                    if (buf[index + 2] == 0x01)//1号终端就是客厅温度和灯模块                                    {                                        if (buf[index + 3] == 0x01)                                        {                                            button_keting_deng.BackColor = Color.Yellow;                                        }                                        else                                        {                                            button_keting_deng.BackColor = Color.DarkGray;                                        }                                    }                                    if (buf[index + 2] == 0x02)//2号终端就是卧室温度和灯模块                                    {                                        if (buf[index + 3] == 0x01)                                        {                                            button_woshi_deng.BackColor = Color.Yellow;                                        }                                        else                                        {                                            button_woshi_deng.BackColor = Color.DarkGray;                                        }                                    }                                    if (buf[index + 2] == 0x05)//5号终端就是厨房烟雾和灯模块                                    {                                        if (buf[index + 3] == 0x01)                                        {                                            button_chufang_deng.BackColor = Color.Yellow;                                        }                                        else                                        {                                            button_chufang_deng.BackColor = Color.DarkGray;                                        }                                    }                                    if (buf[index + 2] == 0x04)//4号终端就是卫生间温度和灯模块                                    {                                        if (buf[index + 3] == 0x01)                                        {                                            button_weishengjian_deng.BackColor = Color.Yellow;                                        }                                        else                                        {                                            button_weishengjian_deng.BackColor = Color.DarkGray;                                        }                                    }                                }                                /****************************************************/                            }                        }                    }                    catch (Exception)                    {                    }                }));            }            catch (Exception)            {                                throw;            }        }        /*启动服务器*/        private void button_Start_Server_Click(object sender, EventArgs e)//点击启动服务器        {            if (socketstart_or_stop)                return;                /**************创建一个终端节点*****************/                IPAddress ip = IPAddress.Parse(textBox_IP.Text);//创建终结点EndPoint                IPEndPoint localep = new IPEndPoint(ip, 4567);//把ip和端口转化为IPEndpoint实例,用于socket侦听时绑定                                /*************创建一个监听并启动监听***************************/                listener = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);                listener.Bind(localep);//把负责监听的socket套接字绑定到主机的端口                listener.Listen(10);//设置监听队列长度                threadWatch = new Thread(WatchConnectioning);                threadWatch.IsBackground = true;                threadWatch.Start();                                /****************设置状态****************************/                socketstart_or_stop = true;//设置启动服务器启动标志为真                this.button_Start_Server.Enabled = false;//启动服务器按钮被按下后,变为灰色不可用。                this.button_Stop_Server.Enabled = true;//关闭服务器按钮变为可用状态                label_server_state.Text = "服务器已开启";        }        /*监听*/        void WatchConnectioning()        {            while(true)   //4、循环等待客户端连接            {                Socket sokConnection = listener.Accept();//创建一个负责通信的套接字                dict.Add(sokConnection.RemoteEndPoint.ToString(), sokConnection);                Thread thrRec = new Thread(RecMsg);                thrRec.IsBackground = true;                thrRec.Start(sokConnection);                dictThread.Add(sokConnection.RemoteEndPoint.ToString(), thrRec);                MessageBox.Show("客户端连接成功");            }        }        /*5、接受recieve*/         void RecMsg(object socketClientpara)        {            Socket socketClient = socketClientpara as Socket;            while(true)            {                byte[] arrMsgRec = new byte[8];                try                {                    socketClient.Receive(arrMsgRec);                    string writecomMsg = System.Text.Encoding.UTF8.GetString(arrMsgRec);                    comm.WriteLine(writecomMsg);                }                catch (SocketException ex)                {                    MessageBox.Show("有客户端被关闭");                    return;                }                catch (Exception ex)                {                    return;                }            }        }         /*6、发送*/        void sockSend(byte[] arrMsg)        {            foreach (Socket s in dict.Values)            {                s.Send(arrMsg);            }        }        private void button_Stop_Server_Click(object sender, EventArgs e)        {            if (!socketstart_or_stop)                return;            listener.Close();            threadWatch.Abort();            socketstart_or_stop = false;            this.button_Start_Server.Enabled = true;//启动服务器按钮不可用            this.button_Stop_Server.Enabled = false;//停止服务器按钮是灰色不可用            label_server_state.Text = "服务器已关闭";        }        private void button_keting_deng_Click(object sender, EventArgs e)        {            byte[] mingling = new byte[4];            mingling[0] = 0x2A; //pc向协调器发送数据            mingling[1] = 0x01; //控制灯的命令            mingling[2] = 0x01; //控制1号节点,就是客厅的灯            if (button_keting_deng.BackColor == Color.DarkGray)//如果灯标志取反为真            {                mingling[3] = 0x01;//点亮灯                comm.Write(mingling, 0, 4);                button_keting_deng.BackColor = Color.Yellow;            }            else            {                mingling[3] = 0x00;//熄灭灯                comm.Write(mingling, 0, 4);                button_keting_deng.BackColor = Color.DarkGray;            }        }        private void button_woshi_deng_Click(object sender, EventArgs e)        {            byte[] mingling = new byte[4];            mingling[0] = 0x2A; //pc向协调器发送数据            mingling[1] = 0x01; //控制灯的命令            mingling[2] = 0x02; //控制2号节点,就是卧室的灯            if (button_woshi_deng.BackColor == Color.DarkGray)//如果灯标志取反为真            {                mingling[3] = 0x01;//点亮灯                comm.Write(mingling, 0, 4);                button_woshi_deng.BackColor = Color.Yellow;            }            else            {                mingling[3] = 0x00;//熄灭灯                comm.Write(mingling, 0, 4);                button_woshi_deng.BackColor = Color.DarkGray;            }        }        private void button_weishengjian_deng_Click(object sender, EventArgs e)        {            byte[] mingling = new byte[4];            mingling[0] = 0x2A; //pc向协调器发送数据            mingling[1] = 0x01; //控制灯的命令            mingling[2] = 0x04; //控制4号节点,就是卫生间的灯            if (button_weishengjian_deng.BackColor == Color.DarkGray)//如果灯标志取反为真            {                mingling[3] = 0x01;//点亮灯                comm.Write(mingling, 0, 4);                button_weishengjian_deng.BackColor = Color.Yellow;            }            else            {                mingling[3] = 0x00;//熄灭灯                comm.Write(mingling, 0, 4);                button_weishengjian_deng.BackColor = Color.DarkGray;            }        }        private void button_chufang_deng_Click(object sender, EventArgs e)        {            byte[] mingling = new byte[4];            mingling[0] = 0x2A; //pc向协调器发送数据            mingling[1] = 0x01; //控制灯的命令            mingling[2] = 0x05; //控制5号节点,就是厨房的灯            if (button_chufang_deng.BackColor == Color.DarkGray)//如果灯标志取反为真            {                mingling[3] = 0x01;//点亮灯                comm.Write(mingling, 0, 4);                button_chufang_deng.BackColor = Color.Yellow;            }            else            {                mingling[3] = 0x00;//熄灭灯                comm.Write(mingling, 0, 4);                button_chufang_deng.BackColor = Color.DarkGray;            }        }        private void button_daiji1_Click(object sender, EventArgs e)        {            byte[] mingling = new byte[5];            mingling[0] = 0x2A; //pc向协调器发送数据            mingling[1] = 0x03; //电视的命令            mingling[2] = 0x03; //控制3号节点,就是客厅电视&机顶盒            mingling[3] = keting_dianshiji_kongzhi_or_xuexi;            mingling[4] = 0x00;//电视待机            comm.Write(mingling, 0, 5);        }        private void button_xinxuan_Click(object sender, EventArgs e)        {            byte[] mingling = new byte[5];            mingling[0] = 0x2A; //pc向协调器发送数据            mingling[1] = 0x03; //控制电视的命令            mingling[2] = 0x03; //控制3号节点,就是客厅电视&机顶盒            mingling[3] = keting_dianshiji_kongzhi_or_xuexi;            mingling[4] = 0x01;//电视信号源选择键            comm.Write(mingling, 0, 5);        }        private void button_caidan1_Click(object sender, EventArgs e)        {            byte[] mingling = new byte[5];            mingling[0] = 0x2A; //pc向协调器发送数据            mingling[1] = 0x03; //控制电视的命令            mingling[2] = 0x03; //控制3号节点,就是客厅电视盒机顶盒            mingling[3] = keting_dianshiji_kongzhi_or_xuexi;            mingling[4] = 0x02;//电视菜单键            comm.Write(mingling, 0, 5);        }        private void button_yinliang_jia1_Click(object sender, EventArgs e)        {            byte[] mingling = new byte[5];            mingling[0] = 0x2A; //pc向协调器发送数据            mingling[1] = 0x03; //控制电视的命令            mingling[2] = 0x03; //控制3号节点,就是客厅电视盒机顶盒            mingling[3] = keting_dianshiji_kongzhi_or_xuexi;            mingling[4] = 0x03;//电视音量+键            comm.Write(mingling, 0, 5);        }        private void button_yinliang_jian1_Click(object sender, EventArgs e)        {            byte[] mingling = new byte[5];            mingling[0] = 0x2A; //pc向协调器发送数据            mingling[1] = 0x03; //控制电视的命令            mingling[2] = 0x03; //控制3号节点,就是客厅电视盒机顶盒            mingling[3] = keting_dianshiji_kongzhi_or_xuexi;            mingling[4] = 0x04;//电视音量—键            comm.Write(mingling, 0, 5);        }        private void button_up1_Click(object sender, EventArgs e)        {            byte[] mingling = new byte[5];            mingling[0] = 0x2A; //pc向协调器发送数据            mingling[1] = 0x03; //控制电视的命令            mingling[2] = 0x03; //控制3号节点,就是客厅电视盒机顶盒            mingling[3] = keting_dianshiji_kongzhi_or_xuexi;            mingling[4] = 0x05;//电视上键            comm.Write(mingling, 0, 5);        }        private void button_down1_Click(object sender, EventArgs e)        {            byte[] mingling = new byte[5];            mingling[0] = 0x2A; //pc向协调器发送数据            mingling[1] = 0x03; //控制电视的命令            mingling[2] = 0x03; //控制3号节点,就是客厅电视盒机顶盒            mingling[3] = keting_dianshiji_kongzhi_or_xuexi;            mingling[4] = 0x06;//电视下键            comm.Write(mingling, 0, 5);        }        private void button_zuo1_Click(object sender, EventArgs e)        {            byte[] mingling = new byte[5];            mingling[0] = 0x2A; //pc向协调器发送数据            mingling[1] = 0x03; //控制电视的命令            mingling[2] = 0x03; //控制3号节点,就是客厅电视盒机顶盒            mingling[3] = keting_dianshiji_kongzhi_or_xuexi;            mingling[4] = 0x07;//电视左键            comm.Write(mingling, 0, 5);        }        private void button_you1_Click(object sender, EventArgs e)        {            byte[] mingling = new byte[5];            mingling[0] = 0x2A; //pc向协调器发送数据            mingling[1] = 0x03; //控制电视的命令            mingling[2] = 0x03; //控制3号节点,就是客厅电视盒机顶盒            mingling[3] = keting_dianshiji_kongzhi_or_xuexi;            mingling[4] = 0x08;//电视右键            comm.Write(mingling, 0, 5);        }        private void button_queding1_Click(object sender, EventArgs e)        {            byte[] mingling = new byte[5];            mingling[0] = 0x2A; //pc向协调器发送数据            mingling[1] = 0x03; //控制电视的命令            mingling[2] = 0x03; //控制3号节点,就是客厅电视盒机顶盒            mingling[3] = keting_dianshiji_kongzhi_or_xuexi;            mingling[4] = 0x09;//电视确定键            comm.Write(mingling, 0, 5);        }        private void keting_dianshiji_kongzhi_CheckedChanged(object sender, EventArgs e)        {            if (keting_dianshiji_kongzhi.Checked)                keting_dianshiji_kongzhi_or_xuexi = 0x6F;        }        private void keting_dianshiji_xuexi_CheckedChanged(object sender, EventArgs e)        {            if (keting_dianshiji_xuexi.Checked)                keting_dianshiji_kongzhi_or_xuexi = 0x7F;        }        private void keting_jidinghe_kongzhi_CheckedChanged(object sender, EventArgs e)        {            if (keting_jidinghe_kongzhi.Checked)                keting_jidinghe_kongzhi_or_xuexi = 0x6F;        }        private void keting_jidinghe_xuexi_CheckedChanged(object sender, EventArgs e)        {            if (keting_jidinghe_xuexi.Checked)                keting_jidinghe_kongzhi_or_xuexi = 0x7F;        }        private void groupBoxTV_Enter(object sender, EventArgs e)        {        }        private void button_daiji2_Click(object sender, EventArgs e)        {            byte[] mingling = new byte[5];            mingling[0] = 0x2A; //pc向协调器发送数据            mingling[1] = 0x03; //电视的命令            mingling[2] = 0x03; //控制3号节点,就是客厅电视&机顶盒            mingling[3] = keting_jidinghe_kongzhi_or_xuexi;            mingling[4] = 0x15;//电视待机            comm.Write(mingling, 0, 5);        }        private void button_caidan_Click(object sender, EventArgs e)        {            byte[] mingling = new byte[5];            mingling[0] = 0x2A; //pc向协调器发送数据            mingling[1] = 0x03; //电视的命令            mingling[2] = 0x03; //控制3号节点,就是客厅电视&机顶盒            mingling[3] = keting_jidinghe_kongzhi_or_xuexi;            mingling[4] = 0x16;//电视待机            comm.Write(mingling, 0, 5);        }        private void button_yinliang_jia2_Click(object sender, EventArgs e)        {            byte[] mingling = new byte[5];            mingling[0] = 0x2A; //pc向协调器发送数据            mingling[1] = 0x03; //电视的命令            mingling[2] = 0x03; //控制3号节点,就是客厅电视&机顶盒            mingling[3] = keting_jidinghe_kongzhi_or_xuexi;            mingling[4] = 0x17;//电视待机            comm.Write(mingling, 0, 5);        }        private void button_yinliang_jian2_Click(object sender, EventArgs e)        {            byte[] mingling = new byte[5];            mingling[0] = 0x2A; //pc向协调器发送数据            mingling[1] = 0x03; //电视的命令            mingling[2] = 0x03; //控制3号节点,就是客厅电视&机顶盒            mingling[3] = keting_jidinghe_kongzhi_or_xuexi;            mingling[4] = 0x18;//电视待机            comm.Write(mingling, 0, 5);        }        private void button_pindao_jia2_Click(object sender, EventArgs e)        {            byte[] mingling = new byte[5];            mingling[0] = 0x2A; //pc向协调器发送数据            mingling[1] = 0x03; //电视的命令            mingling[2] = 0x03; //控制3号节点,就是客厅电视&机顶盒            mingling[3] = keting_jidinghe_kongzhi_or_xuexi;            mingling[4] = 0x19;//电视待机            comm.Write(mingling, 0, 5);        }        private void button_pindao_jian2_Click(object sender, EventArgs e)        {            byte[] mingling = new byte[5];            mingling[0] = 0x2A; //pc向协调器发送数据            mingling[1] = 0x03; //电视的命令            mingling[2] = 0x03; //控制3号节点,就是客厅电视&机顶盒            mingling[3] = keting_jidinghe_kongzhi_or_xuexi;            mingling[4] = 0x1A;//电视待机            comm.Write(mingling, 0, 5);        }        private void button_up2_Click(object sender, EventArgs e)        {            byte[] mingling = new byte[5];            mingling[0] = 0x2A; //pc向协调器发送数据            mingling[1] = 0x03; //电视的命令            mingling[2] = 0x03; //控制3号节点,就是客厅电视&机顶盒            mingling[3] = keting_jidinghe_kongzhi_or_xuexi;            mingling[4] = 0x1B;//电视待机            comm.Write(mingling, 0, 5);        }        private void button_down2_Click(object sender, EventArgs e)        {            byte[] mingling = new byte[5];            mingling[0] = 0x2A; //pc向协调器发送数据            mingling[1] = 0x03; //电视的命令            mingling[2] = 0x03; //控制3号节点,就是客厅电视&机顶盒            mingling[3] = keting_jidinghe_kongzhi_or_xuexi;            mingling[4] = 0x1C;//电视待机            comm.Write(mingling, 0, 5);        }        private void button_zuo2_Click(object sender, EventArgs e)        {            byte[] mingling = new byte[5];            mingling[0] = 0x2A; //pc向协调器发送数据            mingling[1] = 0x03; //电视的命令            mingling[2] = 0x03; //控制3号节点,就是客厅电视&机顶盒            mingling[3] = keting_jidinghe_kongzhi_or_xuexi;            mingling[4] = 0x1D;//电视待机            comm.Write(mingling, 0, 5);        }        private void button_you2_Click(object sender, EventArgs e)        {            byte[] mingling = new byte[5];            mingling[0] = 0x2A; //pc向协调器发送数据            mingling[1] = 0x03; //电视的命令            mingling[2] = 0x03; //控制3号节点,就是客厅电视&机顶盒            mingling[3] = keting_jidinghe_kongzhi_or_xuexi;            mingling[4] = 0x1E;//电视待机            comm.Write(mingling, 0, 5);        }        private void button_queding2_Click(object sender, EventArgs e)        {            byte[] mingling = new byte[5];            mingling[0] = 0x2A; //pc向协调器发送数据            mingling[1] = 0x03; //电视的命令            mingling[2] = 0x03; //控制3号节点,就是客厅电视&机顶盒            mingling[3] = keting_jidinghe_kongzhi_or_xuexi;            mingling[4] = 0x1F;//电视待机            comm.Write(mingling, 0, 5);        }        private void textBox_weishengjian_wendu_TextChanged(object sender, EventArgs e)        {        }    }}