C#与NetworkStream异步读写 [英] C# Asynchronous read and write with NetworkStream

查看:1250
本文介绍了C#与NetworkStream异步读写的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我建立了一个服务器,该服务器接收来自客户端的请求并给出取决于请求类型的响应.如果请求类型为流式传输,则服务器必须发送数据数组.在服务器流式传输数据时,客户端可能会发送停止请求以停止流式传输.如果请求和响应是在同一TCP连接上传输的,则服务器仅在所有数据完成向客户端的流传输时才接收停止请求.我认为我必须使用异步写入来解决此问题.这是我的代码:

首先,我创建一个循环以接收来自客户端的连接:

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());
         }
       }
}



ClientInteraction类的In Process函数:



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);

                }
            }
}



在HandleRequest函数中,如果请求的流,我将以数组的形式将数据发送给客户端:



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.

推荐答案

当您使用线程并正确使用它们时,它使异步操作变得多余.使用线程是更好的方法.我认为异步操作是在尚未引入线程的时候发明的(我记得,当我开始使用Linux时,只有进程,每个进程都是单线程的,因为尚未引入线程API;那时Window NT已经存在了.已发布;并且具有线程).

如何停止串流?您可以在一些数据块中进行流式传输.在块之间,您可以轮询请求状态以查看是否存在停止流式传输的请求.这应该导致流循环中断.使用线程同步,请求状态应在线程之间互锁.在这种情况下,最好的机制可能是System.Threading.ReaderWriterLockSlim,因为该请求经常被读取而很少被写入.请参阅 http://msdn.microsoft.com/en-us/library/system.threading .readerwriterlockslim.aspx [ ^ ].该请求放置在单独的请求线程中,该线程从另一个网络流中读取请求,执行流传输的线程是另一个线程.

或者,您可以使用Thread.Abort中止请求线程中的流线程.这是一种非常安全的机制(基于非常聪明的异常种子机制),但应谨慎使用.特别是,异常终止线程处理异常System.Threading.ThreadAbortException以在异常退出后进行清理非常重要.未能正确清理可能导致各种不愉快的问题,甚至出现死锁.

—SA
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


这篇关于C#与NetworkStream异步读写的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆