socket异步传输,发送和接收缓冲区都设为1024,在局域网内传文件峰值只能到800K/s,而且传输一个5M的文件接收端都程序最后会占到100多M内存,发送端(手机)就更别提了,本来就只有40多M RAM了,发送超过10M的文件一定会报OutOfMemory。我大概知道问题在哪,但确实不知道如何解决。发送和接收的代码如下,请大大们有空时指点下。
        /// 发送数据
        public void Send(Socket handler, byte[] data)
        {
            StateObject obj = new StateObject();
            obj.workSocket = handler;
            obj.senddatalength = 0; //用来记录已发送多少数据,主要是为了知道发送进度。
            obj.senddata = data ;  //这句肯定是占内存的大头,可是如果不把要发送的数据储存在这,发送回调里怎么知道接下来应该发送哪一段数据呢?
            int len = bufferlength;
            if (obj.senddata.Length< StateObject.BufferSize)
            {
                len = obj.senddata.Length;
            }
            handler.BeginSend(obj.senddata, 0, len, 0,
                 new AsyncCallback(SendCallback), obj);
        }        /// 发送回调
        private void SendCallback(IAsyncResult ar)
        {
            StateObject obj = (StateObject)ar.AsyncState;
            int bytesSent = obj.workSocket.EndSend(ar);
            obj.senddatalength = obj.senddatalength + bytesSent;
            if (bytesSent == 0)
            {
                if (sendcompleted != null)
                {
                    sendcompleted();
                }
                obj.workSocket.Shutdown(SocketShutdown.Both);
                obj.workSocket.Close();
            }
            else
            {
                if (sddata != null)
                {
                    sddata(obj.senddatalength);
                }
                int sendlength = bufferlength;
                if (obj.senddatalength + bufferlength > obj.senddata.Length)
                {
                    sendlength = obj.senddata.Length - obj.senddatalength;
                }
                obj.workSocket.BeginSend(obj.senddata, obj.senddatalength, sendlength, 0, 
                     new AsyncCallback(SendCallback), obj); //通过senddatalength来确定这次发送哪段数据 
            }
        }
        
        ///接收回调
        public void readCallback(IAsyncResult ar)
        {
            StateObject state = (StateObject)ar.AsyncState;
            Socket handler = state.workSocket;
            int bytesRead;
            try
            {
                bytesRead = handler.EndReceive(ar);
            }
            catch (Exception)
            {
                return;
            }
            if (bytesRead > 0)
            {
                byte[] tempbt = new byte[bytesRead];
                Array.Copy(state.buffer, 0, tempbt, 0, bytesRead);
                state.data.AddRange(tempbt); //state.data是arraylist 用来储存已经接收到的数据
                if (rcdata != null)
                {
                    rcdata(state.data.Count); //事件  报告已接收多少数据
                }
                state.buffer = new Byte[bytesRead];
                state.workSocket.BeginReceive(state.buffer, 0, bytesRead, 0,
                    new AsyncCallback(readCallback), state);            }
            else
            {
                state.workSocket.Shutdown(SocketShutdown.Both);
                state.workSocket.Close();
                
                if (receivecompleted!=null)
                {
                    receivecompleted(state);
                }
            }
        }

解决方案 »

  1.   


    是啊,我也在想,不知道大家在做socket传输时,是先把文件拆了再发,还是先读进内存再分批发送呢。。
      

  2.   

    C#的socket真的效率很低,建议传输部分写成C++的,然后用C#来调用;
    文件分块的代码用C#来写,这样速度会快很多很多;
      

  3.   

    http://www.csharpwin.com/csharpresource/1135.shtml这里有篇socket的文章,原码相当的不错,有md5验证、接收者可选择接收或拒绝等等,但用的是udp。可惜手机上没有udp类,不然.... 呵呵 
      

  4.   

    就是像C#调用C++函数一样,你的C++库最好导出函数(建立/关闭连接,收/发数据),因为C#没有办法用C++的类,