2017-10-13 53 views
2

我正在构建一个网络扫描实用程序的应用程序,并遇到一些问题,同时在列表视图中显示字符串。C#字符串缺少WindowsForm中的字符应用程序

我通过套接字请求和字节编码找到本地远程机器的Netbios名称,当我在列表视图中显示结果时,域名完全不显示,但是当我导出该列表视图行的文本时在.csv文件中包含机器的NetBios名称的子项目,它将正确显示像“COMPUTER1-WORKGROUP”这样的整个字符串,例如,在列表视图中它将只显示“COMPUTER1”。

在这里,您可以看到在Windows应用程序列表视图显示:

enter image description here

正如你可以在“喃的Netbios”栏的第一行只显示“NVRSERVEUR”

在看

然后当我将ListViewItem.SubItem.Text写入一个.csv文件时,如下图所示,它显示“NVRSERVEUR-IRIS”,其中IRIS代表网络域名。

enter image description here

这里是我使用的检索NetBIOS计算机名称,网络域名的任务代码:

static Task<NetworkInfosWrapper> getNetBiosNameAsyncReply(PingReply reply) 
    { 
     var tcs = new TaskCompletionSource<NetworkInfosWrapper>(); 
     byte[] receiveBuffer = new byte[1024]; 
     Socket requestSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); 
     requestSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 100); 
     EndPoint remoteEndPoint = new IPEndPoint(IPAddress.Parse(reply.Address.ToString()), 137); 
     IPEndPoint originEndPoint = new IPEndPoint(IPAddress.Any, 0); 
     requestSocket.Bind(originEndPoint); 
     SocketAsyncEventArgs e = new SocketAsyncEventArgs(); 
     e.SetBuffer(NameRequest, e.Offset, NameRequest.Count()); 
     e.RemoteEndPoint = remoteEndPoint; 
     e.Completed += (obj, sender) => 
     { 
      try 
      { 
       int receivedByteCount = requestSocket.ReceiveFrom(receiveBuffer, ref remoteEndPoint); 
       if (receivedByteCount >= 90) 
       { 
        Encoding enc = new UTF8Encoding(); 
        //Encoding enc = new ASCIIEncoding(); 

        string deviceName = enc.GetString(receiveBuffer, 57, 16).Trim(); 
        string networkName = enc.GetString(receiveBuffer, 75, 16).Trim(); 

        tcs.SetResult(new NetworkInfosWrapper(reply,(deviceName.Trim()+" - "+networkName.Trim()).Replace(" ", ""))); 

       } 
       else 
       { 
        tcs.SetResult(new NetworkInfosWrapper(reply, "N/A")); 
       } 
      } 
      catch 
      { 
       tcs.SetResult(new NetworkInfosWrapper(reply, "N/A")); 
      } 

     }; 
     requestSocket.SendToAsync(e); 
     return tcs.Task; 
    } 

这里是我的主扫描在列表视图显示它功能:

foreach (var netbiosTask in netbiosTasks) 
     { 
      if (netbiosTask.Result.reply.Status == IPStatus.Success) 
      { 
       ListViewItem lvi; 
       addr = IPAddress.Parse(netbiosTask.Result.reply.Address.ToString()); 
       string mac = ScanUtils.getMacByIp(netbiosTask.Result.reply.Address.ToString()); 

       lvi = new ListViewItem(ScanUtils.GetReverseDNS(netbiosTask.Result.reply.Address.ToString(),1000)); 
       lvi.SubItems.Add(netbiosTask.Result.reply.Address.ToString()); 
       lvi.SubItems.Add("UP"); 
       lvi.SubItems.Add(netbiosTask.Result.reply.RoundtripTime.ToString() + " ms"); 
       lvi.SubItems.Add(netbiosTask.Result.netBiosName); 
       lvi.SubItems.Add(mac); 
       lvi.SubItems.Add(ScanUtils.getMacvendor(mac)); 
       listView.Items.Add(lvi); 
       if(progressBar1.Value < progressBar1.Maximum) { 
        progressBar1.Value = progressBar1.Value + 1; 
       } 
       if (!mStopThread) 
       { 
        break; 
       } 
      } 
     } 

这里是我的列表视图的内容导出为.csv文件:

private void enregistrerBtn_Click(object sender, EventArgs e) 
    { 
     StringBuilder csvContent = new StringBuilder(); 
     csvContent.AppendLine("sep=;"); 
     csvContent.AppendLine("Hostname;Adresse IP;Netbios;Adresse Mac;Mac Vendor"); 

     foreach (ListViewItem item in listView.Items) 
     { 
      csvContent.AppendLine(string.Format("{0};{1};{2};{3};{4}", item.SubItems[0].Text, item.SubItems[1].Text, item.SubItems[4].Text, item.SubItems[5].Text, item.SubItems[6].Text)); 
     } 

     string csvPath = Path.GetDirectoryName(System.AppDomain.CurrentDomain.BaseDirectory).ToString() + @"\Resources\networkScan"+ DateTime.Now.ToString("dd-MM-yyyy-hh-mm-ss") +".csv"; 

     File.AppendAllText(csvPath, csvContent.ToString(),Encoding.UTF8); 
    } 

我试着使用ASCII和UTF-8编码为csv写和套接字响应的字节编码。 其他人曾经遇到过这种问题吗?

回答

0

Trim默认情况下不会从字符串中删除空字节,只能删除空格字符。应用Trim专门去除这样的空字节:

string deviceName = enc.GetString(receiveBuffer, 57, 16).Trim('\0'); 
string networkName = enc.GetString(receiveBuffer, 75, 16).Trim('\0'); 

无论你看到空字节字符串后的部分取决于你如何显示它们。当它看到空字节时,listview停止打印文本,用来查看CSV文件(Excel?)的编辑器似乎能够在空字节后继续。

+0

感谢您的快速回答,我刚刚尝试过,确实有效!我不是很有经验,如果我可以通过我自己找到这种东西,我也不会很有经验!我使用Excel是的,我很困惑,现在我明白谢谢你的解释。干杯 –

+0

现在我可以使用一些更多的帮助,因为对于某些设备的网络域名,我有未知的字符显示,如下所示:https://imgur.com/qMKsAlr,你知道我如何检测一些未知字符,或者翻译得更好?谢谢 –

+0

尝试'[TrimFromZero]函数[这个问题](https://stackoverflow.com/questions/1403524/c-sharp-trimming-string-from-first-null-terminator-and-onwards) – NineBerry