C#字符串缺少WindowsForm中的字符应用程序
问题描述:
我正在构建一个网络扫描实用程序的应用程序,并遇到一些问题,同时在列表视图中显示字符串。C#字符串缺少WindowsForm中的字符应用程序
我通过套接字请求和字节编码找到本地远程机器的Netbios名称,当我在列表视图中显示结果时,域名完全不显示,但是当我导出该列表视图行的文本时在.csv文件中包含机器的NetBios名称的子项目,它将正确显示像“COMPUTER1-WORKGROUP”这样的整个字符串,例如,在列表视图中它将只显示“COMPUTER1”。
在这里,您可以看到在Windows应用程序列表视图显示:
正如你可以在“喃的Netbios”栏的第一行只显示“NVRSERVEUR”
在看然后当我将ListViewItem.SubItem.Text写入一个.csv文件时,如下图所示,它显示“NVRSERVEUR-IRIS”,其中IRIS代表网络域名。
这里是我使用的检索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写和套接字响应的字节编码。 其他人曾经遇到过这种问题吗?
答
Trim
默认情况下不会从字符串中删除空字节,只能删除空格字符。应用Trim
专门去除这样的空字节:
string deviceName = enc.GetString(receiveBuffer, 57, 16).Trim('\0');
string networkName = enc.GetString(receiveBuffer, 75, 16).Trim('\0');
无论你看到空字节字符串后的部分取决于你如何显示它们。当它看到空字节时,listview停止打印文本,用来查看CSV文件(Excel?)的编辑器似乎能够在空字节后继续。
感谢您的快速回答,我刚刚尝试过,确实有效!我不是很有经验,如果我可以通过我自己找到这种东西,我也不会很有经验!我使用Excel是的,我很困惑,现在我明白谢谢你的解释。干杯 –
现在我可以使用一些更多的帮助,因为对于某些设备的网络域名,我有未知的字符显示,如下所示:https://imgur.com/qMKsAlr,你知道我如何检测一些未知字符,或者翻译得更好?谢谢 –
尝试'[TrimFromZero]函数[这个问题](https://stackoverflow.com/questions/1403524/c-sharp-trimming-string-from-first-null-terminator-and-onwards) – NineBerry