当然不会有多个ReadCallBack(),这个回调只在接收成功后才调用,并不是在接收的时候调用。所以你只能看到一个ReadCallBack()。因为其它的接收还堵在那里呢。

解决方案 »

  1.   

    代码比较多,没仔细看。其实你的代码并没有太大的问题,之所以出现丢包是因为你同步信号释放的时机不对。
    ReadCallback(IAsyncResult       ar)   回调方法中你第一时间就释放了allDone,这虽然能够第一时间给接收的线程一个信号让其马上开始下一次循环,但你没注意到,其实这个时候 listener还是停留在上次的阻塞状态,在listener.EndReceiveFrom(ar,       ref       tempRemoteEP)方法没执行之前,listener无法接受新的数据,所以,数据发送快了时候自然会丢包。解决办法很简单, allDone.Set()放到int       read       =       s.EndReceiveFrom(ar,       ref       tempRemoteEP)后面执行即可。其实你这个程序没必要异步接收的,反正你的主线程都是经常性地阻塞去监听的,把listener.BeginReceiveFrom改为同步接收:listener.ReceiveFrom然后在开一条新线程处理接收的数据岂不更简单直观?这样你就不需要引入ManualResetEvent手动同步类了。最后需要指明的是,你这样的异步方法任何时候都只是一条ReadCallback线程,vs2005的显示是正确的,异步的本质就是开一条新的县城去同步接收而已。
      

  2.   

    s.close()出现的问题应该是系统会强制抛出一个异常,大致的信息应该是:“远程主机强制关闭了一个现有的连接”之类的
    把s.close()放到try..catch语句里面就可以了。