BinaryFormatter反序列化在反序列化NetworkStream时随机挂起

时间:2012-12-07 22:12:52

标签: c# .net tcp networkstream binaryformatter

我试图在不掩盖真正问题区域的情况下尽可能省略尽可能多的代码。如果有人需要查看完整代码,请告诉我。

因此,我们构建了一个简单的死简单TCP应用程序,它可以缓解数据库连接,并处理来自单个节点的所有入站数据库请求。此代码处理大约200,000个连接(请求和响应),然后在接收请求时随机将在BinaryFormatter.Deserialize方法上挂起。有没有人有任何关于为什么会这样的想法?

没有生成异常,它只是无限期挂起。

服务器代码:

public class TCPServer
{
    /// <summary>
    /// The listener which listens for inbou nd requests.
    /// </summary>
    private TcpListener _tcpListener;

    /// <summary>
    /// The thread the inbound listener operates on.
    /// </summary>
    private Thread _listenerThread;

    private static object       _lockObject = new object();

    public TCPServer()
    {
        _tcpListener = new TcpListener( IPAddress.Any, 19926 );
        _listenerThread = new Thread( new ThreadStart( ListenForClients ) );
        _listenerThread.Start();
        //Get the server's ip so that the server can connect to its own database.
        DAL.ServerIP = GetLocalIP();
    }

    /// <summary>
    /// Waits for new clients to communicate.  When a new client request is heard,
    /// the connection is given its own processing thread.
    /// </summary>
    private void ListenForClients()
    {
        _tcpListener.Start();

        while( true )
        {
            TcpClient client = _tcpListener.AcceptTcpClient();
            Thread clientThread = new Thread( delegate()
            {
                //Pass in the Current Thread Number so that it can be locked in
                HandleClientComm( client );
            } );
            clientThread.Start();
        }
    }

    /// <summary>
    /// Handles all of the connections for requests.  After a request is recieved, the
    /// TcpClient is passed to this method in its own thread for processing.  This is
    /// where all of the magic happens.  Here we deserialize the NetworkStream and 
    /// use the resulting object to determine which request the client is making, and
    /// respond appropriately.
    /// </summary>
    /// <param name="client"></param>
    private void HandleClientComm( object client )
    {
        lock( _lockObject )
        {
            Response response = new Response();
            TcpClient tcpClient = (TcpClient) client;
            try
            {   
                NetworkStream clientStream = tcpClient.GetStream();

                IFormatter formatter = new BinaryFormatter();
                object result = formatter.Deserialize( clientStream );

                //Determine which type of request this is
                Response response = new Response();

                //Code Omitted, Determine which type of request, and use that to formulate the response.

                RespondToClient( tcpClient, response );
            }
            catch( Exception e )
            {
                response = new Response();
                response.ErrorMessage = e.ToString();
                RespondToClient( tcpClient, response );
            } 
        }
    }

    private void RespondToClient( TcpClient client, Response response )
    {
        try
        {
            IFormatter formatter = new BinaryFormatter();
            NetworkStream stream = client.GetStream();
            formatter.Serialize( stream, response );

            stream.Close();
            client.Close();
        }
        catch( Exception e )
        {
            throw e;
        }
    }
}

客户代码:

public class TCPClient
{
    public static string ServerIP = "192.168.2.200";

    private static Response RequestTCP<T>(T request)
    {
        try
        {
            TcpClient client = new TcpClient();
            IPEndPoint serverEndPoint = new IPEndPoint( IPAddress.Parse( ServerIP ), 19926 );

            client.Connect( serverEndPoint );
            NetworkStream stream = client.GetStream();
            IFormatter formatter = new BinaryFormatter();

            formatter.Serialize( stream, request );
            Response response = ( Response ) formatter.Deserialize( stream );
            return response;
        }
        catch( Exception e )
        {
            return new Response( "Error with the Response: " + e.ToString() );
        }
    }
}

0 个答案:

没有答案