1、  while(true){
                 allDone.Reset();
                 server.BeginAccept(new AsyncCallback(Accept), server);
                 allDone.WaitOne();
             }修改为1、  server.BeginAccept(new AsyncCallback(Accept), server);
就是这样!真正的异步处理程序,没有循环、没有阻塞、非常简洁清晰。反而是那种不伦不类、用同步顺序编程的方式来模拟异步的,让你的程序变得复杂和容易死机。

解决方案 »

  1.   

    Begin-End封装的异步主要是利用AsyncCallback回调机制来解决“并发”的问题
    循环开线程的话,里面就不应该再用Begin-End了,用同步方式,需要自己去编程保障线程安全
      

  2.   

    我把循环去了 只能收到一个请求【我是在一台电脑上做的测试,不知道是不是这个问题】namespace ynSER
    {    public partial class Form1 : Form
        {
           
            
            #region  控件控制        public delegate void DELElistbox(string inStr);
            public DELElistbox opelist;        public void OPElistbox(string instr)
            {            listBox1.Items.Add(instr);        }
            #endregion        /// <summary>
            /// 全局变量的定义
            /// </summary>
            Socket server = null;
            Socket recSocket = null;
            Thread strTH = null;
            private ManualResetEvent allDone = new ManualResetEvent(false);
            private ManualResetEvent Done = new ManualResetEvent(false);
            public Form1()
            {
                InitializeComponent();            button2.Enabled = false;
                opelist = new DELElistbox(OPElistbox);
            }
            private void button1_Click(object sender, EventArgs e)
            {             strTH = new Thread(new ThreadStart(strartServer));
                 strTH.Start();
                 listBox1.Items.Clear();
                 listBox1.Items.Add("服务开启...........");
             
                 this.button1.Enabled = false;
                 button2.Enabled = true;        }
        
            /// <summary>
            /// 开启server的线程方法  
            /// </summary>
            public void strartServer()
            {
                         IPAddress local = IPAddress.Parse("127.0.0.1");
                IPEndPoint iep = new IPEndPoint(local, 5050);            server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);            server.Bind(iep);
                server.Listen(20);           // while(true){
                  //  allDone.Reset();
                    server.BeginAccept(new AsyncCallback(Accept), server);
                  //  allDone.WaitOne();
              //  }

               
            }
            /// <summary>
            /// 异步调用  回调函数
            /// </summary>
            /// <param name="iar"></param>
            System.Byte[] buff = null;
            public void Accept(IAsyncResult iar)
            {          // allDone.Set();
                Socket oldserver = null;
                try {               
                // MessageBox.Show("s..........");
                //传入的socket
                oldserver = (Socket)iar.AsyncState;
                //在原始套接字上调用EndAccept方法,返回新的套接字
                recSocket = oldserver.EndAccept(iar);
                listBox1.Invoke(opelist, string.Format(recSocket.RemoteEndPoint + ":连接"));
                //listBox1.Items.Add("有socket连接:" + recSocket.RemoteEndPoint);
                // MessageBox.Show("end..........");
                   
                buff = new Byte[1024];
           
                recSocket.BeginReceive(buff, 0, buff.Length, SocketFlags.None, new AsyncCallback(read_Callback), recSocket);
            
                          //MessageBox.Show("显示获取客户端socket的相关信息" + recSocket.RemoteEndPoint);            }
                catch (SocketException e)
                {
                    MessageBox.Show("接受服务异常:" + e.ToString());
                    oldserver.Close();
                }        }        //接收数据的回调函数
            public void read_Callback(IAsyncResult iar)
            {
                try {
                   
                    Socket so = (Socket)iar.AsyncState;
                    int recv = so.EndReceive(iar);
                    
                    string str = Encoding.ASCII.GetString(buff, 0, recv);                //MessageBox.Show("接受数据的回调函数[" + recv + "]:" + str);
                    //  listBox1.Invoke(opelist, string.Format(recSocket.RemoteEndPoint) + ":" + str);
                    // listBox1.Invoke(opelist, string.Format("接收数据:" + recSocket.RemoteEndPoint.ToString() + str));
                    listBox1.Invoke(opelist, string.Format("接收数据:" +  str));
                    //MessageBox.Show(str);            }
                catch (SocketException e)
                {                //MessageBox.Show(e.ToString());
                    listBox1.Invoke(opelist, string.Format("【异常】:" + e.ToString()));
                }
            
            
            }       //关闭服务的方法
            private void button2_Click(object sender, EventArgs e)
            {                
               //  if(server!=null)   server.Close();            if (MessageBox.Show("确认?", "Confirm Message", MessageBoxButtons.YesNo) ==DialogResult.Yes)     
                {
                    if (strTH != null)
                        server.Close();
                        strTH.Abort();
                                   button1.Enabled = true;
                    button2.Enabled = false; 
                }      
                else         
                {         
                    return;      
                }
                      }        private void button3_Click(object sender, EventArgs e)
            {
                this.listBox1.Items.Clear();
            }    }
    }
      

  3.   

    在你的 Accept 方法中应该调用 BeginAccept。例如:        public void Accept(IAsyncResult iar)
             {
              var session = new MySession
              {
                  client = recSocket = oldserver.EndAccept(iar),
                  readBuffer = new byte[409600],
                  cache = new List<byte>()
              }
              session.client.BeginReceive(session.readBuffer, 0, session.readBuffer.Length, 
                    SocketFlags.None, read_Callback, session);
              server.BeginAccept(new AsyncCallback(Accept), null);
    }
      

  4.   

    public void Accept(IAsyncResult iar)
    {
               var session = new MySession
               {
                   client = server.EndAccept(iar),
                   readBuffer = new byte[409600],
                   cache = new List<byte>()
               }
               session.client.BeginReceive(session.readBuffer, 0, session.readBuffer.Length, 
                     SocketFlags.None, read_Callback, session);
               server.BeginAccept(Accept, null);
     }对于 read_Callback 也是一样,读取 readBuffer 中的字节之后,保存到 cache 中,异步处理 cache 中的命令,并且再次调用 BeginReceive 方法。
      

  5.   

     MySession 是自己封装的?  还有就是  先client = recSocket = oldserver.EndAccept(iar) 
    在  server.BeginAccept(new AsyncCallback(Accept), null);?
    看到这种写发法,我真的搞不懂了,那我写的 public void strartServer()
            {
                         IPAddress local = IPAddress.Parse("127.0.0.1");
                IPEndPoint iep = new IPEndPoint(local, 5050);            server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);            server.Bind(iep);
                server.Listen(20);           // while(true){
                  //  allDone.Reset();
                    server.BeginAccept(new AsyncCallback(Accept), server);
                  //  allDone.WaitOne();
              //  }
               
            }
    这个方法还要进行处理吗 ?
    搞不懂在吗循环接受了,请大师指点一下