【问题标题】:Async TCP Server in .NET Compact framework.NET Compact 框架中的异步 TCP 服务器
【发布时间】:2013-09-07 12:06:39
【问题描述】:

我在 .net 紧凑框架 3.5(控制台应用程序)中编写异步 TCP 服务器,我只使用套接字类作为不支持 .netCF 的 TcpListener。我使用了与 msdn (http://msdn.microsoft.com/en-us/library/fx6588te(v=vs.90).aspx) 中相同的服务器代码。但 2/3 天后我的系统挂起,我的系统是 64 MB RAM 的 ARM 设备。可能的原因是什么。我在同步 TCP 服务器中没有遇到这样的问题。 这是我的代码。

    public void StartListening()
    {
        try
        {
            IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
            IPAddress ipAddress = ipHostInfo.AddressList[0];
            IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 8001);

            // Create a TCP/IP socket.
            Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            // Bind the socket to the local endpoint and listen for incoming connections.
            listener.Bind(localEndPoint);
            listener.Listen(4);

            while (true)
            {
                try
                {
                    // Start an asynchronous socket to listen for connections.
                    listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);

                    // Wait until a connection is made before continuing.
                    allDone.WaitOne();
                }
                catch (Exception pEx)
                {
                    _serverLog.WriteFile(pEx);
                }
            }
        }
        catch (Exception pEx)
        {
            _serverLog.WriteFile(pEx);
        }
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="ar"></param>
    public void AcceptCallback(IAsyncResult ar)
    {
        allDone.Set();

        Socket listener = (Socket)ar.AsyncState;
        Socket handler = listener.EndAccept(ar);

        //listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);

        StateObject state = new StateObject();
        state.workSocket = handler;
        handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);

        //listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
    }

    /// <summary>
    /// 
    /// </summary>
    public void ReadCallback(IAsyncResult ar)
    {
        StateObject state = (StateObject)ar.AsyncState;
        Socket handler = state.workSocket;

        string localIP = handler.RemoteEndPoint.ToString();
        var _port = localIP.Split(':');
        string _ip = _port[0] + ":" + _port[1];

        int bytesRead = handler.EndReceive(ar);

        if (bytesRead > 0)
        {
            state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
            _receivedData.Enqueue(state.sb.ToString());

            Send(handler, " - ACK - Data Received.");

            //ThreadPool.QueueUserWorkItem(new WaitCallback(ProcessData), _ip);
            this.ProcessData(_ip);
        }
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="handler"></param>
    /// <param name="data"></param>
    private void Send(Socket handler, String data)
    {
        // Convert the string data to byte data using ASCII encoding.
        byte[] byteData = Encoding.ASCII.GetBytes(data);

        // Begin sending the data to the remote device.
        handler.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), handler);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="ar"></param>
    private void SendCallback(IAsyncResult ar)
    {
        try
        {
            // Retrieve the socket from the state object.
            Socket handler = (Socket)ar.AsyncState;

            // Complete sending the data to the remote device.
            int bytesSent = handler.EndSend(ar);

            handler.Shutdown(SocketShutdown.Both);
            handler.Close();
        }
        catch (Exception pEx)
        {
            _serverLog.WriteFile(pEx);
        }
    }

【问题讨论】:

  • 也许您可以更具体地了解“系统挂起”:整个设备是否挂起、您的应用程序是否被阻塞、是否停止接受连接请求或有什么症状?您是否跟踪过您的应用程序/系统的内存消耗/cpu 负载等?
  • 您好 Roland,系统挂起意味着只有应用程序会阻塞,而不是操作系统。是的,它将停止接受连接。我们跟踪了内存使用情况,它逐渐增加,CPU 负载也随之增加。

标签: c# sockets tcp compact-framework


【解决方案1】:

也许它是您尚未在此处发布的部分,但我无法在任何地方看到您清空 StringBuffer state.sb 或 Queue _receivedData 的代码(仅假设按名称/方法的类型)。填充这两个资源可能会使您的系统挂起,因为在某些时候没有更多的内存......

【讨论】:

  • 您好 Roland,我正在以另一种方法对 _receivedData 队列进行出队。并且每次我创建新的 StateObject 时,StringBuffer state.sb 都会设置为 null。
猜你喜欢
  • 2010-10-22
  • 1970-01-01
  • 2014-12-22
  • 2018-01-25
  • 1970-01-01
  • 1970-01-01
  • 2014-02-21
  • 2019-01-04
相关资源
最近更新 更多