locked
Concurrent Remoting and socket connections

    Question

  • Hello

    Having been trying to find the root of this problem for several days I now hope that you can help me.

    I’m implementing a distributed file system – consisting of, at the moment, a testing client (C), a http-server (H) and a file server (F) - with the following setup:

    H acts as an external interface to F, that is any given C connect to one H in order to access files at F. The communication between H and F uses remoting, ie. F registers a FileServerObject which interfaces the local file system which acts as the file storage. Testing H and F alone works fine.

    The communication between C and H uses regular sockets and uses the HTTP1.1 protocol for communication. These two work fine together.

    The problem then is when I try to test the system as a whole. When trying to authorize (using a custom implemented certificate driven authorization protocol) H suddenly starts to act weird when reading data from the NetworkStream based on the socket connected to C. It simply stops reading data at the stream at various points in the authorization process.

    Somehow the remoting setup effects the communication with the clients. Sometimes all works perfectly, other times certificates or encrypted secrets are never read at H. How can this be?

    No exceptions are ever throws, the NetworkStram.Read(…) simply blocks as no data are available. Have the remoting framework somehow consumed the data?

    I’ve included the method that reads from the NetworkStream for you to see.

    If you have any questions that would clarify my problem, please feel free to ask.

    private byte[] ReadPut()
    {
        //Validate for content-length header
        if (!_lastRequest.Headers.ContainsKey("Content-Length"))
        {
            WriteHttpResponse(HttpResponseCodes.BadRequest, "Content-Length header missing");
            return null;
        }
        else
        {
            int contentLength = int.Parse(_lastRequest.Headers["Content-Length"]);
            //Log("Content-Length: " + contentLength);
            byte[] fullContent = new byte[contentLength];

            int readBytesTotal = 0;
            while (readBytesTotal < contentLength)
            {
                int readBytes = _networkStream.Read(fullContent, readBytesTotal, (contentLength - readBytesTotal < 1024 ? contentLength - readBytesTotal : 1024));
                readBytesTotal += readBytes;

                if (readBytes == 0)
                    break;
            }
            if (readBytesTotal == 0)
                return null;
            else
            {

               // Console.WriteLine(ASCIIEncoding.Default.GetString(fullContent));
                return fullContent;
            }
        }
    }

    Best reagards,
    Thomas René Sidor
    Sunday, September 24, 2006 4:18 PM

All replies

  • Sorry for the double post, but the system returned an error when posting.

    Best reagards,
    Thomas René Sidor
    Sunday, September 24, 2006 4:20 PM
  • Ok, apparently the code does not work even if i disable the remoting part at this moment. Communication between the client and http server stops at random, although some data always get send. I.e. I send a http request with some headers and a body – the headers are read using a StreamReader created on top of the NetworkStream – this always works without problems. The problem occurs when reading the body (using the previously posted method) from the NetworkStream.

    Any suggestions as to how this can be?

    The client is implemented using HttpWebReqeust / HttpWebResponse and the server accepts connections using a TcpListener which accepts TcpClients.

    For the purpose of development I have the client start the http server and file server processes – could this influence on the networkstream?

    Below is the code that accepts new incoming connections.

     private void ListeningLoop()
    {
        Log("Starting HttpServer");
        bool exitLoop = false;

        TcpListener listener = new TcpListener(new IPEndPoint(IPAddress.Parse("127.0.0.1"), _port));
        // Registering TcpChannel for remoting
        TcpChannel channel = new TcpChannel();
        ChannelServices.RegisterChannel(channel, true);
     
        Log("HttpServer up and running. Listening on port " + _port);
        listener.Start();
        // Listening for incomming connection to the HttpServer
        while (true)
        {
            // If we for some reason need to stop the server, neat cleanup can be handled here
            if (exitLoop)
            {
                Cleanup();
                break;
            }
            try
            {
                TcpClient client = listener.AcceptTcpClient();
                ConnectionHandlerInstance connectionHandler = new ConnectionHandlerInstance(client);
                Thread connectionHandlerTread = new Thread(new ThreadStart(connectionHandler.HandleConnection));
                connectionHandlerTread.Start();
            }
            catch (Exception)
            {
                //Log(e.ToString());
                Log("Failed to accept connection");
            }
        }
    }

    I would appreciate any feedback.

    Best reagards,
    Thomas René Sidor
    Monday, September 25, 2006 12:22 PM