udp listener不会收集所有数据

时间:2014-08-19 05:52:02

标签: c# udp

我写了这个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);
}

0 个答案:

没有答案