首页 > 代码库 > 【智能家居v1.0项目】C#实现scoket通信

【智能家居v1.0项目】C#实现scoket通信

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



技术分享

以下是服务器客户端

//以下的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<string, Socket> dict = new Dictionary<string, Socket>();
        Dictionary<string, Thread> dictThread = new Dictionary<string, Thread>();

        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)
        {

        }


    }
}




【智能家居v1.0项目】C#实现scoket通信