如何在C#中计算UDP传输速率(kbps)?
首先,我知道UDP不是一个可靠的协议,但我需要在UDP中使用它,我知道最终可能发生的后果 让我们假设我有一个长的如何在C#中计算UDP传输速率(kbps)?,c#,sockets,udp,transfer,rate,C#,Sockets,Udp,Transfer,Rate,首先,我知道UDP不是一个可靠的协议,但我需要在UDP中使用它,我知道最终可能发生的后果 让我们假设我有一个长的字节数组,我将它分成32个字节的块,放入一个列表。这意味着发送的每个数据包的长度为32字节 这些数据包将以foreach循环发送,我不在乎它们是否到达目的地。这意味着我不期待主持人的确认(至少目前如此) 我的问题是,在服务器接收数据包时,如何计算当前的传输速率(最好是以kbps为单位) 我对如何实现这样的计算有些困惑…如果您的问题是“我如何计算传输速率”,您可以将下载的字节总数除以经过
字节
数组,我将它分成32个字节的块,放入一个列表
。这意味着发送的每个数据包的长度为32字节
这些数据包将以foreach
循环发送,我不在乎它们是否到达目的地。这意味着我不期待主持人的确认(至少目前如此)
我的问题是,在服务器接收数据包时,如何计算当前的传输速率(最好是以kbps为单位)
我对如何实现这样的计算有些困惑…如果您的问题是“我如何计算传输速率”,您可以将下载的字节总数除以经过的总秒数
bytes
--------- = transfer rate
seconds
用C#测量时间的一个好方法是类,因为计算机科学中的K是1024(或2^10),你可以将字节数除以1024(或移位),然后将其除以下载千字节数所需的秒数
如果您对平均传输速率感兴趣,则需要每隔一段时间测量下载的字节数。您可以使用二维列表来完成此操作,其中包含测量点、下载的字节和所用的时间。为简单起见,将其拆分为一个进行计算的类
private readonly Stopwatch watch;
private readonly long[,] average;
public .ctor() {
// use 10 measure points, for a larger or smaller average, adjust the 10
average = new long[10, 2];
watch = Stopwatch.StartNew();
}
public long BytesTransferred {
set {
for (int i = average.GetLength(0) - 1; i > 0; --i) {
average[i, 0] = average[i - 1, 0];
average[i, 1] = average[i - 1, 1];
}
average[0, 0] = sent = value;
average[0, 1] = watch.ElapsedMilliseconds;
}
}
public long TransferRate {
get {
int l = average.GetLength(0) - 1;
double bytes = average[0, 0] - average[l, 0];
double seconds = (average[0, 1] - average[l, 1]) / 1000d;
return (long)(bytes / seconds);
}
}
在下载方法中,中断一个新线程,创建上述类的实例,并调用
ByTestTransferred=totalBytes代码>在每个间隔中。每次调用TransferRate时都会计算转帐率。请注意,它是字节/秒,如果您需要另一个单位,请相应地除以1024。我们在fireBwall上使用一个简单的系统,每次检查时都会更新传输速率。它还存储发送的全部信息。我刚刚从fireBwall的Google代码页上复制了这个
/// <summary>
/// Class to manage an adapters total transfered data
/// </summary>
public class BandwidthCounter
{
/// <summary>
/// Class to manage an adapters current transfer rate
/// </summary>
class MiniCounter
{
public uint bytes = 0;
public uint kbytes = 0;
public uint mbytes = 0;
public uint gbytes = 0;
public uint tbytes = 0;
public uint pbytes = 0;
DateTime lastRead = DateTime.Now;
/// <summary>
/// Adds bits(total misnomer because bits per second looks a lot better than bytes per second)
/// </summary>
/// <param name="count">The number of bits to add</param>
public void AddBytes(uint count)
{
bytes += count;
while (bytes > 1024)
{
kbytes++;
bytes -= 1024;
}
while (kbytes > 1024)
{
mbytes++;
kbytes -= 1024;
}
while (mbytes > 1024)
{
gbytes++;
mbytes -= 1024;
}
while (gbytes > 1024)
{
tbytes++;
gbytes -= 1024;
}
while (tbytes > 1024)
{
pbytes++;
tbytes -= 1024;
}
}
/// <summary>
/// Returns the bits per second since the last time this function was called
/// </summary>
/// <returns></returns>
public override string ToString()
{
if (pbytes > 0)
{
double ret = (double)pbytes + ((double)((double)tbytes / 1024));
ret = ret / (DateTime.Now - lastRead).TotalSeconds;
lastRead = DateTime.Now;
string s = ret.ToString();
if (s.Length > 6)
s = s.Substring(0, 6);
return s + " Pb";
}
else if (tbytes > 0)
{
double ret = (double)tbytes + ((double)((double)gbytes / 1024));
ret = ret / (DateTime.Now - lastRead).TotalSeconds;
lastRead = DateTime.Now;
string s = ret.ToString();
if (s.Length > 6)
s = s.Substring(0, 6);
return s + " Tb";
}
else if (gbytes > 0)
{
double ret = (double)gbytes + ((double)((double)mbytes / 1024));
ret = ret / (DateTime.Now - lastRead).TotalSeconds;
lastRead = DateTime.Now;
string s = ret.ToString();
if (s.Length > 6)
s = s.Substring(0, 6);
return s + " Gb";
}
else if (mbytes > 0)
{
double ret = (double)mbytes + ((double)((double)kbytes / 1024));
ret = ret / (DateTime.Now - lastRead).TotalSeconds;
lastRead = DateTime.Now;
string s = ret.ToString();
if (s.Length > 6)
s = s.Substring(0, 6);
return s + " Mb";
}
else if (kbytes > 0)
{
double ret = (double)kbytes + ((double)((double)bytes / 1024));
ret = ret / (DateTime.Now - lastRead).TotalSeconds;
lastRead = DateTime.Now;
string s = ret.ToString();
if (s.Length > 6)
s = s.Substring(0, 6);
return s + " Kb";
}
else
{
double ret = bytes;
ret = ret / (DateTime.Now - lastRead).TotalSeconds;
lastRead = DateTime.Now;
string s = ret.ToString();
if (s.Length > 6)
s = s.Substring(0, 6);
return s + " b";
}
}
}
private uint bytes = 0;
private uint kbytes = 0;
private uint mbytes = 0;
private uint gbytes = 0;
private uint tbytes = 0;
private uint pbytes = 0;
MiniCounter perSecond = new MiniCounter();
/// <summary>
/// Empty constructor, because thats constructive
/// </summary>
public BandwidthCounter()
{
}
/// <summary>
/// Accesses the current transfer rate, returning the text
/// </summary>
/// <returns></returns>
public string GetPerSecond()
{
string s = perSecond.ToString() + "/s";
perSecond = new MiniCounter();
return s;
}
/// <summary>
/// Adds bytes to the total transfered
/// </summary>
/// <param name="count">Byte count</param>
public void AddBytes(uint count)
{
// overflow max
if ((count * 8) >= Int32.MaxValue)
return;
count = 8 * count;
perSecond.AddBytes(count);
bytes += count;
while (bytes > 1024)
{
kbytes++;
bytes -= 1024;
}
while (kbytes > 1024)
{
mbytes++;
kbytes -= 1024;
}
while (mbytes > 1024)
{
gbytes++;
mbytes -= 1024;
}
while (gbytes > 1024)
{
tbytes++;
gbytes -= 1024;
}
while (tbytes > 1024)
{
pbytes++;
tbytes -= 1024;
}
}
/// <summary>
/// Prints out a relevant string for the bits transfered
/// </summary>
/// <returns></returns>
public override string ToString()
{
if (pbytes > 0)
{
double ret = (double)pbytes + ((double)((double)tbytes / 1024));
string s = ret.ToString();
if (s.Length > 6)
s = s.Substring(0, 6);
return s + " Pb";
}
else if (tbytes > 0)
{
double ret = (double)tbytes + ((double)((double)gbytes / 1024));
string s = ret.ToString();
if (s.Length > 6)
s = s.Substring(0, 6);
return s + " Tb";
}
else if (gbytes > 0)
{
double ret = (double)gbytes + ((double)((double)mbytes / 1024));
string s = ret.ToString();
if (s.Length > 6)
s = s.Substring(0, 6);
return s + " Gb";
}
else if (mbytes > 0)
{
double ret = (double)mbytes + ((double)((double)kbytes / 1024));
string s = ret.ToString();
if (s.Length > 6)
s = s.Substring(0, 6);
return s + " Mb";
}
else if (kbytes > 0)
{
double ret = (double)kbytes + ((double)((double)bytes / 1024));
string s = ret.ToString();
if (s.Length > 6)
s = s.Substring(0, 6);
return s + " Kb";
}
else
{
string s = bytes.ToString();
if (s.Length > 6)
s = s.Substring(0, 6);
return s + " b";
}
}
}
//
///类来管理传输的数据总量
///
公共类带宽计数器
{
///
///类来管理当前传输速率
///
类微型计数器
{
公共uint字节=0;
公共uint KB=0;
公共单位兆字节=0;
公共单位GB=0;
公共uint T字节=0;
公共uint字节=0;
DateTime lastRead=DateTime.Now;
///
///添加位(由于每秒的位数看起来比每秒的字节数好得多,所以用词不当)
///
///要添加的位数
公共void AddBytes(uint计数)
{
字节+=计数;
而(字节>1024)
{
千字节++;
字节-=1024;
}
而(千字节>1024)
{
兆字节++;
KB-=1024;
}
而(兆字节>1024)
{
GB++;
兆字节-=1024;
}
而(GB>1024)
{
tbytes++;
GB-=1024;
}
而(t字节>1024)
{
pbytes++;
t字节-=1024;
}
}
///
///返回自上次调用此函数以来每秒的位数
///
///
公共重写字符串ToString()
{
如果(字节数>0)
{
双ret=(双)字节+((双)((双)字节/1024));
ret=ret/(DateTime.Now-lastRead).TotalSeconds;
lastRead=DateTime.Now;
字符串s=ret.ToString();
如果(s.长度>6)
s=s.子串(0,6);
返回s+“Pb”;
}
否则如果(t字节>0)
{
双字节速率=(双)兆字节+((双)((双)兆字节/1024));
ret=ret/(DateTime.Now-lastRead).TotalSeconds;
lastRead=DateTime.Now;
字符串s=ret.ToString();
如果(s.长度>6)
s=s.子串(0,6);
返回s+“Tb”;
}
否则如果(GB>0)
{
double-ret=(double)GB+((double)((double)MB/1024));
ret=ret/(DateTime.Now-lastRead).TotalSeconds;
lastRead=DateTime.Now;
字符串s=ret.ToString();
如果(s.长度>6)
s=s.子串(0,6);
返回s+“Gb”;
}
否则,如果(兆字节>0)
{
double-ret=(double)MB+((double)((double)KB/1024));
ret=ret/(DateTime.Now-lastRead).TotalSeconds;
lastRead=DateTime.Now;
字符串s=ret.ToString();
如果(s.长度>6)
s=s.子串(0,6);
返回s+“Mb”;
}
否则如果(千字节>0)
{
double-ret=(double)kbytes+((double)((double)字节/1024));
ret=ret/(DateTime.Now-lastRead).TotalSeconds;
lastRead=DateTime.Now;
字符串s=ret.ToString();
如果(s.长度>6)
s=s.子串(0,6);
返回s+“Kb”;
}
其他的
{
双ret=字节;
ret=ret/(DateTime.Now-lastRead).TotalSeconds;
lastRead=DateTime.Now;
字符串s=ret.ToString();
如果(s.长度>6)
s=s.子串(0,6);
返回s+“b”;
}
}
}
私有uint字节=0;
专用uint KB=0;
专用uint兆字节=0;
私人单位