string[,]经常赋值不上,导致绘制listview时报错未将对象引用设置到对象的实例错误

小白本人没学过c#,如果发现低级错误,各位大侠勿嘲笑...
说正题,winform做个设备管理界面,在学习论坛各位大神的帖子中也算是基本完成了开发,但在使用中发现问题,流程是登陆后获取到本机网卡,点击 button发送搜索数据包,等待所有设备回应,将所有设备信息显示到listview中,我在存储设备信息时用的是二维string[,], 将 string[,]再绘制到listview中,问题出在string[,]经常赋值不上,导致绘制listview时报错“未将对象引用设置到对象的实 例”。具体请看代码注释<重点问题>,里边还有两个关于socket的<附加问题>,也请大家帮忙看看,多谢!


         private string[,] scanList = new string[,] { };
        private int scanIndex;
        private static System.Timers.Timer procTimer;
        static Socket mySocket;
        private static IPEndPoint dstPoint;

        private void ToolStripButton5_Click(object sender, EventArgs e)
        {
            DeviceScanPublicValue.searchPort = int.Parse(ToolStripTextBox1.Text);
            DeviceScanPublicValue.devManagePort = 1208;

            /*附加问题1:因为后边有1s的搜索窗口,为防止再次点击按钮触发socket套接字错误,把按钮去使能了,定时器里再使能
             *这里也想请教大家,怎么在发生socket套接字错误时恢复,我现在是一旦发生这种错误就死掉了,只能重新打开应用
             */
            ToolStripButton5.Text = "搜索中...";
            ToolStripButton5.Enabled = false;   

            scanList = new string[511, 11];//最多511个设备
            scanIndex = 0;
            ListView2.Items.Clear();

            byte[] sendData = { 0x44, 0x55, 0x44, 0x55, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20 };

            //Socket处理
            mySocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            mySocket.Bind(new IPEndPoint(IPAddress.Parse(DeviceScanPublicValue.localIP), DeviceScanPublicValue.searchPort));

            Thread recvThread = new Thread(ReciveMessage)
            {
                IsBackground = true
            };
            recvThread.Start();
            dstPoint = new IPEndPoint(IPAddress.Broadcast, DeviceScanPublicValue.devManagePort);
            string hostName = Dns.GetHostName();
            mySocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
            Thread sendThread = new Thread(SendMessage);
            sendThread.Start(sendData);

            //创建一个1000ms定时的定时器,因为不知道有多少设备,给个1s的搜索窗口,定时器结束绘制listview
            procTimer = new System.Timers.Timer(1000);
            procTimer.Elapsed += OnTimedEvent;
            procTimer.AutoReset = false;
            procTimer.Enabled = true;
            procTimer.Start();
        }

        private void SendMessage(object obj)
        {
            byte[] message = (byte[])obj;
            mySocket.SendTo(message, dstPoint);
        }

        private void ReciveMessage()
        {
            EndPoint point = new IPEndPoint(IPAddress.Any, DeviceScanPublicValue.devManagePort);
            Thread.Sleep(50);

            /*附加问题2:搜索时,电脑网卡确实收到4个设备回应的报文,但有时就会出现socket接收不全的情况,比如只解析三个设备
             */
            while (true)
            {
                try
                {
                    Thread.Sleep(50);
                    byte[] buffer = new byte[100];
                    int length = mySocket.ReceiveFrom(buffer, ref point);   //接收数据报
                    SearchMessageProc(buffer);
                }
                catch (Exception)
                {

                }
                finally
                {

                }

            }

        }

        struct DeviceList
        {
            public string type;
            public string name;
            public string location;
            public string logicId;
            public string ip;
            public string mac;
            public string port;
            public string model;
            public string timeModel;
            public string timeIn;
            public string status;
            public string topology;
        };

        private void SearchMessageProc(object obj)
        {
            DeviceList devInfo;
            byte[] message = (byte[])obj;
            if (message[0] == 0x44 && message[1] == 0x55 && message[4] == 0x21)
            {
                /*
                解析报文,得到devInfo,不贴代码了,太长了
                */
                //整合搜索设备信息
                string[] deviceScanInfo = { devInfo.name , devInfo.location , devInfo.logicId   , devInfo.ip     , devInfo.mac    ,
                                            devInfo.port , devInfo.model    , devInfo.timeModel , devInfo.timeIn , devInfo.status , devInfo.topology };


                for (int i = 0; i < 11; i++)
                {
                    /*
                    重点问题:就在这,我测试用四个设备,scanList偶尔就会出现其中一个设备信息为null,但deviceScanInfo是正确的,
                    scanIndex也能加到4,这样就导致后边绘制listview时有null报错,百思不得其解
                    */
                    scanList[scanIndex9000, i] = deviceScanInfo[i];
                    scanIndex++;
                }
            }
        }

        private ListViewItem scanDevList;

        private void OnTimedEvent(object sender, ElapsedEventArgs e)
        {
            ListView2.BeginUpdate();
            for (int i = 0; i < scanIndex; i++)
            {
                scanDevList = new ListViewItem
                {
                    Text = (i + 1).ToString()
                };
                for (int j = 0; j < 11; j++)
                {
                    scanDevList.SubItems.Add(scanList[i, j].ToString());
                }
                ListView2.Items.Add(scanDevList);
                ListView2.Items[i].BackColor = Color.Lavender;
            }

            ListView2.EndUpdate();
            ToolStripButton5.Text = "搜索设备";
            ToolStripButton5.Enabled = true;
            mySocket.Shutdown(SocketShutdown.Both);
            mySocket.Close();
            procTimer.Stop();
        }
那你可以這樣改呀,
 for (int i = 0; i < 11; i++)
                {
                    /*
                    重点问题:就在这,我测试用四个设备,scanList偶尔就会出现其中一个设备信息为null,但deviceScanInfo是正确的,
                    scanIndex也能加到4,这样就导致后边绘制listview时有null报错,百思不得其解
                    */
                 if( deviceScanInfo[i]!=null)//當不是null
                   {
   
                    scanList[scanIndex9000, i] = deviceScanInfo[i];
                    scanIndex++;
}
else
{
         //導出日誌,列出設備的詳細信息,然後用調試工具測試這些信息能不能聯通到這台設備
}
                }

感谢!这样是可以规避掉问题,我现在也是判断是否为空再做后续处理,起码可以不让程序死掉。但毕竟还是丢掉了相应的设备信息,目前只能靠重复搜索来保证搜全设备。。。

之前的代码有些地方贴错了,可能误导大家,重贴一下,并且突然想到能否用while语句来执行string[,]赋值,改完小蜜蜂论坛发帖机后效果确实好了很多,listview绘制时也加了些判断。就是不知道while会不会有风险

        private string[,] ne9000List = new string[,] { };
        private int scanIndex9000;
        private static System.Timers.Timer procTimer;
        static Socket mySocket;
        static Thread recvThread;
        static Thread sendThread;
        private static IPEndPoint dstPoint;

       struct DeviceList
        {
            public string type;
            public string name;
            public string location;
            public string logicId;
            public string ip;
            public string mac;
            public string port;
            public string model;
            public string timeModel;
            public string timeIn;
            public string status;
            public string topology;
        };

        private void SearchMessageProc(object obj)
        {
            DeviceList devInfo;
            byte[] message = (byte[])obj;
            if (message[0] == 0x4E && message[1] == 0x53 && message[4] == 0x21)
            {
                  /*devInfo处理
                  */
                string[] deviceScanInfo = { devInfo.name , devInfo.location , devInfo.logicId   , devInfo.ip     , devInfo.mac    ,
                                            devInfo.port , devInfo.model    , devInfo.timeModel , devInfo.timeIn , devInfo.status , devInfo.topology };

                bool scanErr = false;
                    for (int i = 0; i < 11; i++)
                    {
                        if (deviceScanInfo[i] == null)
                            scanErr = true;
                    }

                    if (scanErr == false)
                    {
                        while (ne9000List[scanIndex9000, 0] == null || ne9000List[scanIndex9000, 1] == null || ne9000List[scanIndex9000, 2] == null || ne9000List[scanIndex9000, 3] == null ||
                               ne9000List[scanIndex9000, 4] == null || ne9000List[scanIndex9000, 5] == null || ne9000List[scanIndex9000, 6] == null || ne9000List[scanIndex9000, 7] == null ||
                               ne9000List[scanIndex9000, 8] == null || ne9000List[scanIndex9000, 9] == null || ne9000List[scanIndex9000, 10] == null )
                        {
                            for (int i = 0; i < 11; i++)
                            {
                                ne9000List[scanIndex9000, i] = deviceScanInfo[i];
                            }
                        }
                        scanIndex9000++;
                    }
            }
        }

    private ListViewItem scanDevList;
    private void OnTimedEvent(object sender, ElapsedEventArgs e)
    {
        ListView2.BeginUpdate();
        int validNum9000 = 0;

        for (int i = 0; i < scanIndex9000; i++)
        {
            if (ne9000List[i, 0] != null && ne9000List[i, 1] != null && ne9000List[i, 2] != null && ne9000List[i, 3] != null &&
                ne9000List[i, 4] != null && ne9000List[i, 5] != null && ne9000List[i, 6] != null && ne9000List[i, 7] != null &&
                ne9000List[i, 8] != null && ne9000List[i, 9] != null && ne9000List[i, 10] != null)
            {
                scanDevList = new ListViewItem
                {
                    Text = (validNum9000 + 1).ToString()
                };
                for (int j = 0; j < 11; j++)
                {
                    scanDevList.SubItems.Add(ne9000List[i, j].ToString());
                }
                ListView2.Items.Add(scanDevList);
                ListView2.Items[validNum9000].BackColor = Color.Lavender;
                validNum9000++;
            }
        }

        ListView2.EndUpdate();
        ToolStripButton5.Text = "网络设备搜索";
        ToolStripButton5.Enabled = true;
        mySocket.Shutdown(SocketShutdown.Both);
        mySocket.Close();
        procTimer.Stop();
    }

 

发布了74 篇原创文章 · 获赞 0 · 访问量 3094

猜你喜欢

转载自blog.csdn.net/netyou/article/details/104390126