用Socket的BeginSend 和EndSend,还有相应的Recv...

解决方案 »

  1.   

    class StateObj//异步读取的状态信息
    {
        public NetworkStream ns; //异步读取的网络数据流(从网络上读取数据)
        public FileStream fs; //异步读取的文件数据流(将网络上读取的数据写入文件)
        public byte[] rb; //读取Buffer
        public long tb; //读取计数器
        public long fb; //文件尺寸
        public TextBox tt; //用于输出调试信息的文本框
        public StateObj(NetworkStream a, FileStream b, byte[] c, long d, long e, TextBox f)
        {
            ns = a;
            fs = b;
            rb = c;
            tb = d;
            fb = e;
            tt = f;
        }
    }AsyncCallback cb = new AsyncCallback(NetReadCallBack);//建立回叫函数代表
    StateObj so = new StateObj(stream, fs, readBuffer, totalBytes, fileSize, textBox3);//建立异步读取状态信息对象
    stream.BeginRead(readBuffer, 0, readBuffer.Length, cb, so);//开始异步读取
    //异步读取回叫函数
    public static void NetReadCallBack(IAsyncResult ar)
    {
    StateObj so = (StateObj)ar.AsyncState; //得到状态信息 FileStream fs = so.fs; //得到文件操作流
    NetworkStream ns = so.ns; //得到网络数据流
    long tb = so.tb; //得到接收计数器
    long fb = so.fb; //得到文件尺寸
    byte[] readBuffer = so.rb; //得到读取Buffer
    TextBox tt = so.tt; //用于输出调试信息的文本框
    int bytes = ns.EndRead(ar); //本次异步读取结束,返回读取字节数 fs.Write(readBuffer, 0, bytes); //将数据写入本地文件
    so.tb = tb + (long)bytes; //读取计数器累加
    tt.Text = so.tb.ToString(); //在文本框中显示读取计数器
    if(so.tb < fb) //如果没有读取完毕
    {
    AsyncCallback cb = new AsyncCallback(NetReadCallBack);//重建回叫函数
    ns.BeginRead(readBuffer, 0, readBuffer.Length, cb, so);//开始下一轮异步读取
    }
    else //如果已经读取完毕
    {
    fs.Close(); //文件流关闭,并显示结束对话框
    MessageBox.Show("File transport accomplish!\nTotal bytes of transport is: " + so.tb.ToString() + " (Bytes)\n" + bytes.ToString()); }
    }