void ShowMsg()
        {
            while (true)
            {
                byte[] bytes = new byte[1024 * 1024 * 3];       //3M
                for(int i=0;i<dic.Count;i++)
                {
                    Socket socket = dic.Values.ElementAt(i);
                    int length = socket.Receive(bytes);
                    if (length > 0)
                    {
                        string Msg = System.Text.Encoding.UTF8.GetString(bytes, 0, length);
                        txtReceive.AppendText(dic.Keys.ElementAt(i) + " --- " + Msg + "\r\n");
                    }
                }
            }
        }
ShowMsg是一个线程。
dic是一个字典,其中的Values值为所有客户端的Socket。for循环的意思是检测所有的Socket,如果收到数据则将数据取出来。
故障如下:当只有一个客户端时,没有问题,发什么,收什么。当客户端超过两个时,麻烦来了,客户端一发送后,服务器端没反应,这时只要客户端二发送信息,服务器会将客户端二的信息收到,而且将之前客户端一的信息收到。
我不清楚是不是因为for循环在线程里导致出现这种情况,还是因为什么,总感觉for循环没有完整的执行。
请教大家,谢谢!

解决方案 »

  1.   

    socket.Receive(bytes);这句代码好像会造成阻塞,你DEBUG了没。
    客户端一发送没反应,可能是for的阻塞正好还在客户端二的socket.Receive停留着
      

  2.   

    我debuge了,将断点放在for里面,第一次发送时不会触发断点,第二个客户端发送时才会进入到for里面。
    我不知道“阻塞”是怎样产生的,应该怎样去避免呢?
      

  3.   

    参见
    http://bbs.csdn.net/topics/390518338
      

  4.   

    楼上误会了,一楼的代码是服务器端的接收数据。因为服务器端会接收到多个客户端发来的数据,所以不知道如何处理。
    一楼的代码是循环所有与客户端连接的Socket,检测是否有数据发送至服务器端,可惜产生了阻塞不知道如何处理。
    谢谢。
      

  5.   

    楼上说的是对的
    Socket.Receive方法  是一个阻塞的方法
    当没有接受到数据的时候  程序运行到这里就停止了
    一直等到能够接收到数据  这个程序才会继续走下去你用for(int i)
    {
    Socket[i].Receive
    }
    是肯定会造成这种问题的
    因为例如 i = 1的时候 就是第一个Socket 开始接收  但是没接收到的时候就会卡住在这里
    所以会造成 i = 2 的 Socket 没有调用这个方法解决方法  要不就每个Socket单独开个线程来 Receive
    要不就 BeginReceive 异步来接收
      

  6.   


    既然某一个Socket.Receive可能造成阻塞  那么其他的Socket.Receive就调用不了  所以就应该每个Socket对应一个线程(或者使用异步编程)  不能把所有的socket.Receive放在一个线程中去 参见#4
      

  7.   

    客户端连接服务端时,服务端就应该建一个单独的线程来连接,然后用Socket.Receive来等待接收数据,各个Socket之间不会有影响,为什么要用个for循环来做呢Socket也可以分辨出是哪个客户端发送过来的数据啊。
      

  8.   

    类A
    try{
                            Socket socket = listener.Accept();//此线程将在此监听
                            CClient cClient = new CClient(socket);
                          
                            Thread thread = new Thread(new ThreadStart(cClient.WaitForSendData));
                            thread.Name = socket.RemoteEndPoint.ToString();
                            thread.Start();
    }
    类CClient   public void WaitForSendData()
            {
                try
                {
                    while (thisSocket != null)
                    {                    if (thisSocket.Connected == false)
                        {
                           
                            break;
                        }
                        string data = string.Empty;
                        bytes = new byte[1024];
                        thisSocket.Blocking = true;
                        int bytesRec = 0;                    if (thisSocket.Available == 0)
                        {
                            Thread.Sleep(500);
                            continue;
                        }              
      

  9.   

    private void btnListen_Click(object sender, EventArgs e)
            {
                socket_Server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                string HostName = Dns.GetHostName();
                IPHostEntry IpEntry = Dns.GetHostEntry(HostName);
                string strIpAddr = IpEntry.AddressList[0].ToString();
                IPAddress ServerIP = IPAddress.Parse(strIpAddr);
                int port = 9001;
                IPEndPoint point = new IPEndPoint(ServerIP, port); 
                socket_Server.Bind(point);     
                socket_Server.Blocking = false;
                socket_Server.Listen(10);
               txtBoxListenMsg.AppendText("监听成功!\r\n");
                btnListen.Enabled = false;
                AsyncCallback aCallback = new AsyncCallback(AcceptCallback);
                socket_Server.BeginAccept(aCallback, socket_Server);        }
            public void AcceptCallback(IAsyncResult ar)
            {
                Socket listener = null;
                Socket handler = null;
                try
                {
                    byte[] buffer = new byte[1024];
                    listener = (Socket)ar.AsyncState;
                    handler = listener.EndAccept(ar);
                    handler.NoDelay = false;
                    object[] obj = new object[2];
                    obj[0] = buffer;
                    obj[1] = handler;
                    handler.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), obj);
                    AsyncCallback aCallback = new AsyncCallback(AcceptCallback);
                    listener.BeginAccept(aCallback, listener);
                }catch(Exception e){MessageBox.Show(e.ToString());}
            }
            public void ReceiveCallback(IAsyncResult ar)
            {
                try
                {
                    object[] obj = new object[2];
                    obj = (object[])ar.AsyncState;
                    byte[] buffer = (byte[])obj[0];
                    Socket handler = (Socket)obj[1];
                    string content = string.Empty;
                    int bytesRead = handler.EndReceive(ar);
                    if (bytesRead > 0)
                    {
                        content += Encoding.Unicode.GetString(buffer, 0, bytesRead);
                        if (content.IndexOf("<Client Quit>") > -1)
                        {
                            string str = content.Substring(0, content.LastIndexOf("<Client Quit>"));
                            txtReceive.Text = str + "\t\n" + txtReceive.Text;
                        }
                        else
                        {
                            byte[] buffernew = new byte[1024];
                            obj[0] = buffernew;
                            obj[1] = handler;
                            handler.BeginReceive(buffernew, 0, buffernew.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), obj);
                            txtReceive.Text = content + " ----- " + handler.RemoteEndPoint.ToString() +"\t\n" + txtReceive.Text;
                        }                }
                }
                catch (Exception e) { MessageBox.Show(e.ToString()); }
            }