在登陆过程中客户端新建了个线程来和服务器会话
 private void 登陆_Load(object sender, EventArgs e)
        {
            contactWithServer = new ContactWithServer(this, user);
            Thread clientcontactserverThread = new Thread(new ThreadStart(contactWithServer.contact));
            clientcontactserverThread.Start();           
        }
客户端接收程序
  public void contact()
     {
        //receiveIpep = new IPEndPoint(IPAddress.Parse(serverIP), 8888);
        ////sendIpep = new IPEndPoint(IPAddress.Parse(serverIP), 6666);       //服务器端接收端口
        //udpReceiveClient = new UdpClient(receiveIpep);
        receiveIpep = null;       
        try
        {
            udpReceiveClient = new UdpClient(8888);
            while (true)
            {
                MessageBox.Show("where"); 
                byte[] data = udpReceiveClient.Receive(ref receiveIpep);
                if (data.Length < 20)                       //只有命令
                    commandStr = Encoding.ASCII.GetString(data);
                else                                       //既有命令又有数据
                {
                    int i = 0;
                    ///取出命令
                    for (i = 0; i < leng; i++)
                    {
                        if (Convert.ToInt32(data[i]) == 0)    //寻找请求中的有效字符的最终位置
                            break;
                    }
                    byte[] cmdbyte = new byte[i];
                    for (int k = 0; k < i; k++)
                    {
                        cmdbyte[k] = data[k];
                    }
                    commandStr = Encoding.ASCII.GetString(cmdbyte);                    
                }
                MessageBox.Show(commandStr, "来自服务器的命令!");
                switch (commandStr)
                {
                    case "LoginSuccess":
                        {
                            登陆.LoginFormDelegate closeDelegate = new 登陆.LoginFormDelegate(loginFormAction);
                            loginForm.Invoke(closeDelegate, new String[] { "close" });
                            loginForm.isFirst = false;         //客户端已登陆成功,下次发给服务器的消息从另一端口发出
                            frm = new 申请及扫描(user, this);
                            frm.ShowDialog();
                        }
                        break;
                    case "LoginFail":
                        {
                            MessageBox.Show("用户名或者密码错误");
                            登陆.LoginFormDelegate clearDelegate = new 登陆.LoginFormDelegate(loginFormAction);
                            loginForm.Invoke(clearDelegate, new String[] { "clear" });
                        }
                        break;
                    case "ReFreshData":
                        buff = new byte[data.Length - leng];
                        for (int j = 0; j < data.Length - leng; j++)
                            buff[j] = data[leng + j];
                        memStream = new MemoryStream(buff);
                        memStream.Seek(0, SeekOrigin.Begin);
                        memStream.Flush();
                        DataTable dt = new DataTable();
                        dt = (DataTable)formatter.Deserialize(memStream);
                        memStream.Close();
                        MessageBox.Show("收到服务器的命令");
                        break;
                }
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
            
        }
客户端成功登陆后,程序执行到红字显示的内容后就去执行其它代码了,在此过程中服务器发过来的数据都不能接收,当客户端关闭后才能接收,不知道怎样修改

解决方案 »

  1.   

    ShowDialog会阻塞,你用异步来做就行了。
    与服务器的通讯放在一个独立的线程中,这样与UI相关的交互就不会阻塞了。
      

  2.   

    怎样实现异步呢?线程这块用的也不是很清楚,在客户端哪块new了一个新线程,就是打算用来和服务器沟通的独立线程
      

  3.   

    例子:http://download.csdn.net/detail/caozhy/5287998
      

  4.   

     frm = new 申请及扫描(user, this);
                                frm.ShowDialog();
    包含在 while (true)里面,你每一次都new一个窗体,当然了应该是判断窗体为空才new
    if(frm==null){ frm = new 申请及扫描(user, this);}
     frm.ShowDialog();
      

  5.   

    在线程中,或循环体中的窗体,new时要特别注意判断是否为空,如果每次都new,那么每次都是新的窗体,后面想操作前面窗体的内容,就没办法操作了
      

  6.   

    已经加上了,还是去执行shoudialog时阻塞了,怎样解决呢
      

  7.   

    客户端在加载的时候创建了一个新线程,来接受服务器的消息:
    contactWithServer = new ContactWithServer(this, user);
    Thread clientcontactserverThread = new Thread(new ThreadStart(contactWithServer.ReceiveMsg));
                clientcontactserverThread.Start(); 
       public void ReceiveMsg()
            {
                while (true)
                {
                    lock (this)
                    {
                        // 调用接收回调函数
                        IAsyncResult iar = udpReceiveClient.BeginReceive(new AsyncCallback(ReceiveCallback), udpReceiveState);
                        receiveDone.WaitOne();
                        Thread.Sleep(100);
                    }
                }
            }
            private void ReceiveCallback(IAsyncResult iar)
            {
                UdpState udpReceiveState = iar.AsyncState as UdpState;
                if (iar.IsCompleted)
                {
                    data = udpReceiveState.udpClient.EndReceive(iar, ref udpReceiveState.ipEndPoint);
                    if (data.Length < 20)                       //只有命令
                            commandStr = Encoding.ASCII.GetString(data);
                        else                                       //既有命令又有数据
                        {
                            int i = 0;
                            ///取出命令
                            for (i = 0; i < leng; i++)
                            {
                                if (Convert.ToInt32(data[i]) == 0)    //寻找请求中的有效字符的最终位置
                                    break;
                            }
                            byte[] cmdbyte = new byte[i];
                            for (int k = 0; k < i; k++)
                            {
                                cmdbyte[k] = data[k];
                            }
                            commandStr = Encoding.ASCII.GetString(cmdbyte);                    
                        }
                        MessageBox.Show(commandStr, "来自服务器的命令!");
                        handleMsg(commandStr);                
                    Thread.Sleep(100);
                    receiveDone.Set();               
                }
            }
            private void handleMsg(string commandStr)
            {
                switch (commandStr)
                {
                    case "LoginSuccess":
                        {
                            登陆.LoginFormDelegate closeDelegate = new 登陆.LoginFormDelegate(loginFormAction);
                            loginForm.Invoke(closeDelegate, new String[] { "close" });
                            loginForm.isFirst = false;         //客户端已登陆成功,下次发给服务器的消息从另一端口发出
                            frm = new 申请及扫描(user, this);
                            frm.ShowDialog();
                        }
                        break;
                    case "LoginFail":
                        {
                            MessageBox.Show("用户名或者密码错误");
                            登陆.LoginFormDelegate clearDelegate = new 登陆.LoginFormDelegate(loginFormAction);
                            loginForm.Invoke(clearDelegate, new String[] { "clear" });
                        }
                        break;
                    case "ReFreshData":
                        ///取出数据
                        buff = new byte[data.Length - leng];
                        for (int j = 0; j < data.Length - leng; j++)
                            buff[j] = data[leng + j];
                        memStream = new MemoryStream(buff);
                        memStream.Seek(0, SeekOrigin.Begin);
                        memStream.Flush();
                        DataTable dt = new DataTable();
                        dt = (DataTable)formatter.Deserialize(memStream);
                        memStream.Close();
                        MessageBox.Show("收到服务器的命令");
                        break;
                }
            }客户端这边登陆成功后会跳转到一个新窗体,接着从这个新窗体上给服务器发请求,服务器那边能收到消息,并且也给客户端这边回复了,客户端这边就是不能收到消息,只有关闭窗体时才能收到,自己简单的测试了下,是在frm.ShowDialog();这块停下了,没有接收服务器发来的消息,昨天有人说我的两边的通信方式是同步,改成异步通信后就行了,我就从网上找了个异步通信的例子,彻底照着改了,可是结果还是和昨天一样,不知道我改的哪有问题还是其它别的什么原因
      

  8.   

    比如在form1 中show form2, 
    f2.ShowDialog() 后,除非有方法是写在f2窗体里,或者f2中可以调用你想要的方法,否则,在f2关闭前,f1窗体是阻断状态的
      

  9.   

    可是我是在登陆成功后就把第一个窗体关闭后才执行f2.手dialog的。。