Click here to Skip to main content
15,879,535 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have built a server that receives requests from a client and gives a response that depends on the request Type. If the request type is streaming, the server must send data array. While the server’s streaming data the client may send a stop request to stop the streaming. If the request and the response is transferred on the same TCP connection the server only receives the stop request when all the data has finished streaming to the client. I think I must use Asynchronous write to solve this problem. This is my code:

First I create a loop back to receive connection from clients:

while (!done)
{
       try
       {
          Socket socket = listener.AcceptSocket();
          ClientInteraction clIr = new ClientInteraction(socket, statusList);
          Thread thread = new Thread(new ThreadStart(clIr.Process));
          thread.Start();                                     
        }
        catch (Exception ex)
         {
               Console.WriteLine(ex.ToString());
         }
       }
}


In Process function of ClientInteraction class :

Public void Process()
{
            ns = new NetworkStream(socket);
            while (true)
            {
                try
                {

                        this.myReadBuffer = new byte[socket.ReceiveBufferSize];
                        this.numberOfBytesRead = ns.Read(myReadBuffer, 0, myReadBuffer.Length);

                }
                catch
                {
                    break;
                }
                if (numberOfBytesRead == 0)
                {
                    break;
                }
                else
                {

                    HandleRequest(myReadBuffer, numberOfBytesRead);

                }
            }
}


In HandleRequest Function, if request’s STREAM, I will send data in an array to client:

Public void HanldeRequest(……)
{
    myCompleteMessage = "";
    myCompleteMessage =
               String.Concat(myCompleteMessage, Encoding.ASCII.GetString(myReadBuffer, 0, numberOfBytesRead));
    If(myCompleteMessage == "Stream")
    {
        //I get data and call SendData function
            foreach(.......)
            {
              //get data
              ........
            SendData(data);
            }
    }
}        
   public void SendData(byte[] data)
        {
            try
            {
                //ns.Write(data, 0, data.Length);
                ns.BeginWrite(data, 0, data.Length, new AsyncCallback(StreamData), null);
            }
            catch
            {

            }
        }

        public void StreamData(IAsyncResult asynResult)
        {
            if(asynResult != null)
                ns.EndWrite(asynResult);
        }


With this code, I connected with client, send data to client. But I still can’t receive Stop request until all data is streamed. Please show me the correct way to fix my problem. Thank you.
Posted

1 solution

When you use threads, and use them properly, it renders asynchronous operations redundant; and using threads is a better way. I think asynchronous operations were invented when threads were not yet introduced (I remember, when I started to work with Linux, there were only processes, each process was single-threaded as thread API was not yet introduced; at that time Window NT was already released; and it has threads).

How to stop streaming? You can do streaming in some chunks of data. Between chunks you can poll a request status to see if there is a request to stop streaming; which should cause a break of the streaming loop. The request status should be interlocked between thread using thread synchronization. In this case, the best mechanism is probably System.Threading.ReaderWriterLockSlim because the request is often read but rarely written. See http://msdn.microsoft.com/en-us/library/system.threading.readerwriterlockslim.aspx[^]. The request is placed be the separate request thread which reads requests from a different network stream, the thread performing streaming is another thread.

Alternatively, you can abort streaming thread from the request thread using Thread.Abort. This is very safe mechanism (based on very clever exception seed mechanism), but it should be used with care. In particular, it's very important for the thread to be aborted to handle the exception System.Threading.ThreadAbortException to clean-up after abort. Failure to do proper clean-up can cause different unpleasant problems, even a deadlock.

—SA
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900