客户端为Flash,服务端为c#.net。
现在问题是这样的,当客户端关闭浏览器时,Flash和.net的socket会断开。
但是不知道为什么,.net端挂起的异步send和revice并不会终止,我尝试了调用Shutdown,可是会抛出disposeobject的异常。各位大虾应该怎么办?        private void ReadCallBack(IAsyncResult ar)
        {
            StateObject state = (StateObject)ar.AsyncState;
            int revlen = 0;
            
            try
            {
                revlen = state.workSocket.EndReceive(ar);
            }
            catch (Exception ex)
            {
                Disconnet(state.clientID);                return;
            }            if (revlen == 0)
            {
                try
                {
                    state.workSocket.EndSend(ar);
                }
                catch (Exception ex)
                {
                    log.Error("ReadCallBack EndSend Error - Msg(" + ex.Message + ").");
                }
                Disconnet(state.clientID);                return;
            }            System.IO.MemoryStream ms = new System.IO.MemoryStream(state.buffer, 0, state.buffer.Length);
            FluorineFx.IO.AMFReader reader = new FluorineFx.IO.AMFReader(ms);            while (true)
            {
                if (ms.Position >= ms.Length)
                {
                    state.buffer = new byte[StateObject.BufferSize];                    try
                    {
                        state.workSocket.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallBack), state);
                    }
                    catch (Exception ex)
                    {
                        Disconnet(state.clientID);                        ms.Close();
                        reader.Close();                        return;
                    }                    break;
                }                byte head = reader.ReadByte();                if (head == 170)
                {
                    if (ms.Position + 2 > ms.Length)
                    {
                        byte[] tmpbuff = new byte[StateObject.BufferSize];                        for (int i = 0; i < ms.Length - (ms.Position - 1); i++)
                        {
                            tmpbuff[i] = state.buffer[ms.Position - 1 + i];
                        }                        state.buffer = tmpbuff;                        try
                        {
                            state.workSocket.BeginReceive(state.buffer, (int)(ms.Length - (ms.Position - 1)), (int)(StateObject.BufferSize - (ms.Length - (ms.Position - 1))), 0, new AsyncCallback(ReadCallBack), state);
                        }
                        catch (Exception ex)
                        {
                            RtmpDisconnet(state.clientID);                            ms.Close();
                            reader.Close();                            return;
                        }                        break;
                    }                    ushort len = reader.ReadUInt16();                    if (len > 0 && len < 255)
                    {
                        if (ms.Position + len > ms.Length)
                        {
                            byte[] tmpbuff = new byte[StateObject.BufferSize];                            for (int i = 0; i < ms.Length - (ms.Position - 3); i++)
                            {
                                tmpbuff[i] = state.buffer[ms.Position - 3 + i];
                            }                            state.buffer = tmpbuff;                            try
                            {
                                state.workSocket.BeginReceive(state.buffer, (int)(ms.Length - (ms.Position - 3)), (int)(StateObject.BufferSize - (ms.Length - (ms.Position - 3))), 0, new AsyncCallback(ReadCallBack), state);
                            }
                            catch (Exception ex)
                            {
                                RtmpDisconnet(state.clientID);                                ms.Close();
                                reader.Close();                                return;
                            }                            break;
                        }
                        else
                        {
                            ms.Position += len;                            if (ms.Position + 1 > ms.Length)
                            {
                                byte[] tmpbuff = new byte[StateObject.BufferSize];                                for (int i = 0; i < ms.Length - (ms.Position - len - 1); i++)
                                {
                                    tmpbuff[i] = state.buffer[ms.Position - len - 1 + i];
                                }                                state.buffer = tmpbuff;                                try
                                {
                                    state.workSocket.BeginReceive(state.buffer, (int)(ms.Length - (ms.Position - len - 1)), (int)(StateObject.BufferSize - (ms.Length - (ms.Position - len - 1))), 0, new AsyncCallback(ReadCallBack), state);
                                }
                                catch (Exception ex)
                                {
                                    RtmpDisconnet(state.clientID);                                    ms.Close();
                                    reader.Close();                                    return;
                                }                                break;
                            }                            byte end = reader.ReadByte();                            if (end == 85)
                            {
                                ms.Position = ms.Position - 1 - len;                                int clientID = (int)(reader.ReadUInt16());                                // 转发
                                SendGraphNode sgn = ServerGraph[clientID] as SendGraphNode;                                if (sgn != null)
                                {
                                    Socket nexts = ClientSocket[sgn.NextClientID] as Socket;                                    if (nexts != null && nexts.Connected)
                                    {
                                        byte[] buf = new byte[len + 2 + 2];                                        for (int i = 0; i < len + 2 + 2; i++)
                                        {
                                            buf[i] = state.buffer[(int)(ms.Position - 4 - 1) + i];
                                        }                                        if (nexts.Connected)
                                        {
                                            try
                                            {
                                                nexts.BeginSend(buf, 0, buf.Length, 0, new AsyncCallback(SendCallback), nexts);
                                            }
                                            catch (Exception ex)
                                            {
                                                nexts.Shutdown(SocketShutdown.Both);
                                                nexts.Close();
                                                ClientSocket.Remove(sgn.NextClientID);
                                            }
                                        }
                                    }
                                }                                ms.Position = ms.Position - 2 + len + 1;
                            }
                            else
                            {
                                ms.Position = ms.Position - 1 - len - 1;
                            }
                        }
                    }
                    else
                    {
                        ms.Position -= 1;
                    }
                }
            }            ms.Close();
            reader.Close();
        }

private void SendCallback(IAsyncResult ar)
        {
            Socket soc = (Socket)ar.AsyncState;            try
            {
                soc.EndSend(ar);
            }
            catch (Exception ex)
            {
                return;
            }
        }
Disconnet里面的操作就是

Socket. Shutdown(SocketShutdown.Both);
        socket.Close();

解决方案 »

  1.   

    用代码着色功能啊,看着真累.
    我帮你着色下.方便后面的人看.
    private void ReadCallBack(IAsyncResult ar)
      {
      StateObject state = (StateObject)ar.AsyncState;
      int revlen = 0;
        
      try
      {
      revlen = state.workSocket.EndReceive(ar);
      }
      catch (Exception ex)
      {
      Disconnet(state.clientID);  return;
      }  if (revlen == 0)
      {
      try
      {
      state.workSocket.EndSend(ar);
      }
      catch (Exception ex)
      {
      log.Error("ReadCallBack EndSend Error - Msg(" + ex.Message + ").");
      }
      Disconnet(state.clientID);  return;
      }  System.IO.MemoryStream ms = new System.IO.MemoryStream(state.buffer, 0, state.buffer.Length);
      FluorineFx.IO.AMFReader reader = new FluorineFx.IO.AMFReader(ms);  while (true)
      {
      if (ms.Position >= ms.Length)
      {
      state.buffer = new byte[StateObject.BufferSize];  try
      {
      state.workSocket.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallBack), state);
      }
      catch (Exception ex)
      {
      Disconnet(state.clientID);  ms.Close();
      reader.Close();  return;
      }  break;
      }  byte head = reader.ReadByte();  if (head == 170)
      {
      if (ms.Position + 2 > ms.Length)
      {
      byte[] tmpbuff = new byte[StateObject.BufferSize];  for (int i = 0; i < ms.Length - (ms.Position - 1); i++)
      {
      tmpbuff[i] = state.buffer[ms.Position - 1 + i];
      }  state.buffer = tmpbuff;  try
      {
      state.workSocket.BeginReceive(state.buffer, (int)(ms.Length - (ms.Position - 1)), (int)(StateObject.BufferSize - (ms.Length - (ms.Position - 1))), 0, new AsyncCallback(ReadCallBack), state);
      }
      catch (Exception ex)
      {
      RtmpDisconnet(state.clientID);  ms.Close();
      reader.Close();  return;
      }  break;
      }  ushort len = reader.ReadUInt16();  if (len > 0 && len < 255)
      {
      if (ms.Position + len > ms.Length)
      {
      byte[] tmpbuff = new byte[StateObject.BufferSize];  for (int i = 0; i < ms.Length - (ms.Position - 3); i++)
      {
      tmpbuff[i] = state.buffer[ms.Position - 3 + i];
      }  state.buffer = tmpbuff;  try
      {
      state.workSocket.BeginReceive(state.buffer, (int)(ms.Length - (ms.Position - 3)), (int)(StateObject.BufferSize - (ms.Length - (ms.Position - 3))), 0, new AsyncCallback(ReadCallBack), state);
      }
      catch (Exception ex)
      {
      RtmpDisconnet(state.clientID);  ms.Close();
      reader.Close();  return;
      }  break;
      }
      else
      {
      ms.Position += len;  if (ms.Position + 1 > ms.Length)
      {
      byte[] tmpbuff = new byte[StateObject.BufferSize];  for (int i = 0; i < ms.Length - (ms.Position - len - 1); i++)
      {
      tmpbuff[i] = state.buffer[ms.Position - len - 1 + i];
      }  state.buffer = tmpbuff;  try
      {
      state.workSocket.BeginReceive(state.buffer, (int)(ms.Length - (ms.Position - len - 1)), (int)(StateObject.BufferSize - (ms.Length - (ms.Position - len - 1))), 0, new AsyncCallback(ReadCallBack), state);
      }
      catch (Exception ex)
      {
      RtmpDisconnet(state.clientID);  ms.Close();
      reader.Close();  return;
      }  break;
      }  byte end = reader.ReadByte();  if (end == 85)
      {
      ms.Position = ms.Position - 1 - len;  int clientID = (int)(reader.ReadUInt16());  // 转发
      SendGraphNode sgn = ServerGraph[clientID] as SendGraphNode;  if (sgn != null)
      {
      Socket nexts = ClientSocket[sgn.NextClientID] as Socket;  if (nexts != null && nexts.Connected)
      {
      byte[] buf = new byte[len + 2 + 2];  for (int i = 0; i < len + 2 + 2; i++)
      {
      buf[i] = state.buffer[(int)(ms.Position - 4 - 1) + i];
      }  if (nexts.Connected)
      {
      try
      {
      nexts.BeginSend(buf, 0, buf.Length, 0, new AsyncCallback(SendCallback), nexts);
      }
      catch (Exception ex)
      {
      nexts.Shutdown(SocketShutdown.Both);
      nexts.Close();
      ClientSocket.Remove(sgn.NextClientID);
      }
      }
      }
      }  ms.Position = ms.Position - 2 + len + 1;
      }
      else
      {
      ms.Position = ms.Position - 1 - len - 1;
      }
      }
      }
      else
      {
      ms.Position -= 1;
      }
      }
      }  ms.Close();
      reader.Close();
      }private void SendCallback(IAsyncResult ar)
      {
      Socket soc = (Socket)ar.AsyncState;  try
      {
      soc.EndSend(ar);
      }
      catch (Exception ex)
      {
      return;
      }
      }
    //Disconnet里面的操作就是Socket. Shutdown(SocketShutdown.Both);
      socket.Close();
      

  2.   

    socket的receive函数返回0时代表断开,测试时在两台pc机上做测试。
    不要用一台机器自己连自己做测试,那样socket是不会断开的。
      

  3.   

    这样关闭private void Disconnet()
    {
                try
                {
                    socket.Shutdown(SocketShutdown.Both);
                }
                catch (SocketException ex) { }
                catch (ObjectDisposedException ex) { }
                socket.Close();
    }
      

  4.   


    我明白,receive收到0就是断开,代码理有这个判断,因为整个程序同时需要保持其它的连接,所以有别的连接关闭了socket的可能,因此才又在try catch里面捕获了一个连接断开。
    而且我也没有用自己的机器测试,测试服务器是dell r710 放在电信机房了
      

  5.   

    http://blog.csdn.net/fengyarongaa/article/details/6631953
    我把我博客的一个帖子贴给你
    希望能给你参考
      

  6.   


    我的做法和这个差不多                    try
                        {
                            ClientSocket.Shutdown(SocketShutdown.Both);
                            ClientSocket.Close();                        log.Debug("ClientSocket - Shutdown & Close.");
                        }
                        catch (Exception ex)
                        {
                            log.Error("Shutdown OR Close Socket Error:" + ex.Message);
                        }
    不知道是不是有问题