刚刚接触socket编程,希望大家帮忙分析下,这里先谢谢大家了!
我用c#编写了一个Socket的C/S程序,客户端和服务器端都有界面。参考的是msdn上面的socket异步的代码范例,
(http://kb.cnblogs.com/a/1455703/)
但是现在运行后发现服务器端的界面假死,卡住了,不能拖动、操作等等
服务端有个“监听的按钮”,点击后就出现上面的情况,相应的部分代码如下:// Thread signal.
public static ManualResetEvent allDone = new ManualResetEvent(false); private void btnListen_Click(object sender, EventArgs e)
        {                StartListen();        }public void StartListen()
        {
            try
            {
                
                byte[] bytes = new Byte[1024];                IPAddress ipAddress = IPAddress.Parse("xx.xx.xx.xx");
                IPEndPoint localEndPoint = new IPEndPoint(ipAddress, serverPort);                // 生成一个TCP的socket
                Socket listener = new Socket(AddressFamily.InterNetwork,
                    SocketType.Stream, ProtocolType.Tcp);                listener.Bind(localEndPoint);
                
                listener.Listen(20);                while (true)
                {
                    
                    // Set the event to nonsignaled state.
                    allDone.Reset();                    //开启异步监听socket
                    Console.WriteLine("Waiting for a connection");
                    listener.BeginAccept(new AsyncCallback(AcceptCallback),listener);                    // 让程序等待,直到连接任务完成。在AcceptCallback里的适当位置放置allDone.Set()语句.
                    allDone.WaitOne();
                }            }
            catch (Exception Err)
            {
                throw new Exception("错误:", Err);
            }
        }
        public static void AcceptCallback(IAsyncResult ar)
        {
            //添加此命令,让主线程继续.
            allDone.Set();
            // 获取客户请求的socket
            Socket listener = (Socket)ar.AsyncState;
            Socket handler = listener.EndAccept(ar);            // 造一个容器,并用于接收命令.
            StateObject state = new StateObject();
            state.workSocket = handler;
            handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,new AsyncCallback(ReadCallback), state);
        }
        public static void ReadCallback(IAsyncResult ar)
        {
            String content = String.Empty;            // 从异步state对象中获取state和socket对象.
            StateObject state = (StateObject)ar.AsyncState;
            Socket handler = state.workSocket;            // 从客户socket读取数据. 
            int bytesRead = handler.EndReceive(ar);            if (bytesRead > 0)
            {
                // 如果接收到数据,则存起来
                state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));                // 检查是否有结束标记,如果没有则继续读取
                content = state.sb.ToString();
                if (content.IndexOf("<EOF>") > -1)
                {
                    //所有数据读取完毕.
                    Console.WriteLine("Read {0} bytes from socket. \n Data : {1}",
                        content.Length, content);
                    // 给客户端响应.
                    Send(handler, content);
                }
                else
                {
                    // 接收未完成,继续接收.
                    handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,new AsyncCallback(ReadCallback), state);
                }
            }
        }

解决方案 »

  1.   

    你这哪里是异步呀!while循环一直等待连接,当然会界面假死了!
      

  2.   

    你要用事件监听,有连接过来就处理,启动后,就可以继续执行后续的代码,才不会界面假死!看看这个:一个我经常参考的异步socket通信/url][url=http://www.cnblogs.com/yuanermen/archive/2009/04/02/1428050.html]C#.net 同步异步SOCKET通讯和多线程总结
      

  3.   

    上面连接没弄好!C#.net 同步异步SOCKET通讯和多线程总结
    一个我经常参考的异步socket通信:
    http://www.codeproject.com/KB/IP/AsyncSocketServerandClien/article.JPG
      

  4.   

    StartListen 要在其他线程上做
      

  5.   


    嗯,注意到了,点击时间里面调用了StartListen 方法,而StartListen 方法里面的while死循环一直在执行,所以出现界面假死了;
    现在定义一个线程,用这个线程去执行StartListen方法解决了上述问题
    myThread = new Thread(new ThreadStart(StartListen));
    myThread.Start();
      

  6.   

    while (true)
      {
        
      .....
    Application.DoEvent();
      }
      

  7.   

    msdn上的所谓“异步”是假的异步,只是用了异步操作的那个语句而已,但是(放开来多看调用语句)程序还是同步阻塞模式程序。
      

  8.   

    这样的啊,那能否提供些异步的例子啊(链接地址也行)。刚接触socket,看到人家msdn上这么写的异步就认为是了。还想请教下并发的问题,如果说有N多的客户端同时连接服务器端,向服务器端发送信息,这时候该怎怎么进行处理啊,能大概说下处理的流程吗??期待中......
      

  9.   

            private void btnListen_Click(object sender, EventArgs e)
            {
                Thread t=new Thread(new ThreadStart(StartListen);
                t.IsBackground=true;
                t.Start();
            }
      

  10.   


    汗,我点你给的那个链接进去看到里面确实写得是“同步套接字通信”,看代码也没发现哪里是异步的;
    难道是我理解的错误?能不能说说同步和异步的区别啊,具体的处理流程是怎样的,我刚接触socket;谢谢啦!
      

  11.   

    需要注意的,如果你在子线程(也就是辅线程里面,接受到数据后,需要修改主线程UI界面的显示的数据,那么你会得到“不是在创建控件的线程。”异常。解决方法如下:
    解决方法有两个~第一:
    Control.CheckForIllegalCrossThreadCalls = false;
    线程开始的时候加这么一句,OK,看不到错误了~
    啥都能用了~第二:
    用委托,在05里,每个控件都有个InvokeRequired的属性~
    判断一下是不是true,是的话进行Invoke操作的,完事了~  //建立个委托
    private delegate string returnStrDelegate();//搞个最简单滴取值滴方法~
    private string returnSchool()
      {
      return CB_School.SelectedValue.ToString();
      }//判断一下是不是该用Invoke滴~,不是就直接返回~
    private string returnCB(returnStrDelegate myDelegate)
      {
      if (this.InvokeRequired)
      {
      return (string)this.Invoke(myDelegate);
      }
      else
      {
      return myDelegate();
      }
      }//别的线程里的调用哇~
    string _school = returnCB(returnSchool); 
      

  12.   


    An Asynchronous Socket Server and Client
    你点进去以后,题目应该是这个吧?《异步Socket实例的服务端与客户端》,你在哪里看到是同步了?
      

  13.   


    你的代码里,在按钮单击事件里调用监听方法,那么所有的连接必然会链接到UI线程,既然这样,UI线程必然是假死现象。
      

  14.   

    汗,我点的是你后面说的那个链接“C#.net同步异步SOCKET通讯和多线程总结”,上面那个说链接没有弄好的其实是异步的; 
      

  15.   

    while(true)
    新建一个线程区监听。这样就不会假死。