2017-10-13 54 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