新人c#小白,各位专家帮忙看下,急!!!

潘多拉的浩克 2020-01-18 01:34:35
小白本人没学过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();
}

多谢各位了
...全文
137 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
潘多拉的浩克 2020-01-18
  • 打赏
  • 举报
回复
之前的代码有些地方贴错了,可能误导大家,重贴一下,并且突然想到能否用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();
    }
潘多拉的浩克 2020-01-18
  • 打赏
  • 举报
回复
引用 1 楼 ManBOyyy 的回复:
那你可以這樣改呀,  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 { //導出日誌,列出設備的詳細信息,然後用調試工具測試這些信息能不能聯通到這台設備 }                 }
感谢!这样是可以规避掉问题,我现在也是判断是否为空再做后续处理,起码可以不让程序死掉。但毕竟还是丢掉了相应的设备信息,目前只能靠重复搜索来保证搜全设备。。。
ManBOyyy 2020-01-18
  • 打赏
  • 举报
回复
那你可以這樣改呀,
 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
{
//導出日誌,列出設備的詳細信息,然後用調試工具測試這些信息能不能聯通到這台設備
}
                }

110,566

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧