我写了这个c#代码,它在TPL中执行,这是我的Backgroundworker的任务之一。 它是一个udp服务器监听器,可以通过" run_server"接收取消信号。旗。 当我收集6个事件时,它会产生罚款,但是当我有更多的数据包时,它不会收集剩下的数据包。 我尝试增加TIMEOUT但是没有用。 注意:我使用较短的轮询速率而不是使用超时,因为我希望能够在一秒钟内取消,但希望udp timout为16秒。 我还加入了睡眠,因为民意调查根本没有停顿。 有什么想法吗?
run_server = true;
try
{
Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
// specify timeout to prevent the thread from freezing
const int TIMEOUT = 16000; // millisecond
const int CANCELATION_DELAY = 500; // millisecond
IPEndPoint iep = new IPEndPoint(IPAddress.Any, port);
EndPoint ep = (EndPoint)iep;
sock.Bind(iep);
IPEndPoint remote_ipep = new IPEndPoint(IPAddress.Any, port);
EndPoint remote_ep = (EndPoint)iep;
int iter = 0;
try
{
while (run_server && (iter < (TIMEOUT / CANCELATION_DELAY)))
{
if (sock.Poll(CANCELATION_DELAY, SelectMode.SelectRead))
{
byte[] data = new byte[10240];
int len = sock.Receive(data);
byte[] data2 = new byte[len];
Buffer.BlockCopy(data, 0, data2, 0, len);
Hashtable evt = (Hashtable)BsonReader.Deserialize(data2);
trace.Add(evt);
iter = 0;
}
else
{
iter += 1;
Thread.Sleep(CANCELATION_DELAY);
}
}
}
catch (SocketException)
{
}
catch (ThreadAbortException)
{
Console.WriteLine("Closing the socket");
sock.Close();
}
[UPDATE] 我将代码更改为以下代码。 它收集我的Windows 7上的所有数据包,但是当我在Windows 2008服务器上尝试时,无论超时值如何,它都会丢失一些数据包:
sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
// specify timeout to prevent the thread from freezing
int TIMEOUT = udp_timeout * 1000; // millisecond
const int CANCELATION_DELAY = 1000; // millisecond
IPEndPoint iep = new IPEndPoint(IPAddress.Any, port);
EndPoint ep = (EndPoint)iep;
sock.Bind(iep);
IPEndPoint remote_ipep = new IPEndPoint(IPAddress.Any, port);
EndPoint remote_ep = (EndPoint)iep;
int iter = 0;
try
{
while (run_server && (iter < (TIMEOUT / CANCELATION_DELAY)))
{
// socket poll uses micro-second units
if (sock.Poll(CANCELATION_DELAY * 1000, SelectMode.SelectRead))
{
byte[] data = new byte[1024000];// make a big buffer to allow big packets come in
int len = sock.Receive(data);
byte[] data2 = new byte[len];
Buffer.BlockCopy(data, 0, data2, 0, len);
try
{
Hashtable evt = (Hashtable)BsonReader.Deserialize(data2);
trace.Add(evt);
}catch(Exception ex)
{
Console.WriteLine("Failed to read bson data: " + ex);
}
iter = 0;
}
else
{
iter += 1;
}
}
}
catch (SocketException)
{
// do not worry about socket read timeout exceptions
Console.WriteLine("socket error!");
}
catch (Exception ex)
{
Console.WriteLine(ex);
}