C# 如何加速缓冲WCF传输

C# 如何加速缓冲WCF传输,c#,performance,wcf,nettcpbinding,C#,Performance,Wcf,Nettcpbinding,我在WCF中使用缓冲传输模式方案将压缩文件从服务器传输到客户端。传输在回调中进行,3.7兆字节的文件传输仅需2分钟。 因为我有很多其他的功能在使用这个缓冲模式,所以我不想改变这个方案 以下是我正在使用的绑定,仅供参考 <bindings> <netTcpBinding> <binding name="NetTcpBinding_MyIIService" closeTimeout="00:01:00" openTimeout="00

我在WCF中使用缓冲传输模式方案将压缩文件从服务器传输到客户端。传输在回调中进行,3.7兆字节的文件传输仅需2分钟。 因为我有很多其他的功能在使用这个缓冲模式,所以我不想改变这个方案

以下是我正在使用的绑定,仅供参考

<bindings>
  <netTcpBinding>
    <binding name="NetTcpBinding_MyIIService"
      closeTimeout="00:01:00"
      openTimeout="00:01:00"
      receiveTimeout="00:10:00"
      sendTimeout="00:01:00"
      transactionFlow="false"
      transferMode="Buffered"
      transactionProtocol="OleTransactions"
      hostNameComparisonMode="StrongWildcard"
      listenBacklog="10"
      maxBufferPoolSize="4967294"
      maxBufferSize="4967294"
      maxConnections="10"
      maxReceivedMessageSize="104857600">
      <readerQuotas maxDepth="104857600"
             maxStringContentLength="104857600"
             maxArrayLength="104857600"
             maxBytesPerRead="104857600"
             maxNameTableCharCount="104857600"/>
      <reliableSession ordered="true"
             inactivityTimeout="20:00:10"
             enabled="true"/>
      <security mode="None">
        <transport clientCredentialType="Windows"
             protectionLevel="EncryptAndSign"/>
        <message clientCredentialType="Windows"/>
      </security>
    </binding>
  </netTcpBinding>
</bindings> 

将一个文件放到我的谷歌硬盘共享上大约需要15秒。怎么了。如何提高传输速率?

如果您已经尝试了其他方法,您可以尝试压缩。简而言之,在主机端压缩数据需要1/2秒,在客户端解压需要1/2秒,但是通过有线传输的总有效负载减少了大约1/3

您可以在使用System.Convert.ToBase64String将byte()数组更改为字符串之前压缩它,也可以在发送之前压缩base64字符串。这里有一个C#的小压缩/解压缩类:

使用系统;
使用System.IO;
使用系统IO压缩;
使用系统文本;
名称空间压缩字符串
{
内部静态类压缩程序
{
/// 
///压缩字符串。
/// 
///文本。
/// 
公共静态字符串压缩字符串(字符串文本)
{
byte[]buffer=Encoding.UTF8.GetBytes(文本);
var memoryStream=新的memoryStream();
使用(var gZipStream=new gZipStream(memoryStream,CompressionMode.Compress,true))
{
写入(buffer,0,buffer.Length);
}
memoryStream.Position=0;
var compressedData=新字节[memoryStream.Length];
memoryStream.Read(compressedData,0,compressedData.Length);
var gZipBuffer=新字节[compressedData.Length+4];
块复制(compressedData,0,gZipBuffer,4,compressedData.Length);
BlockCopy(BitConverter.GetBytes(Buffer.Length),0,gZipBuffer,0,4);
返回Convert.ToBase64String(gZipBuffer);
}
/// 
///解压缩字符串。
/// 
///压缩文本。
/// 
公共静态字符串解压缩字符串(字符串压缩文本)
{
字节[]gZipBuffer=Convert.FromBase64String(compressedText);
使用(var memoryStream=new memoryStream())
{
int dataLength=BitConverter.ToInt32(gZipBuffer,0);
memoryStream.Write(gZipBuffer,4,gZipBuffer.Length-4);
var buffer=新字节[数据长度];
memoryStream.Position=0;
使用(var gZipStream=new gZipStream(memoryStream,CompressionMode.Decompress))
{
读取(buffer,0,buffer.Length);
}
返回Encoding.UTF8.GetString(缓冲区);
}
}
}
}

祝你好运。我发现这个压缩实用程序快速且易于使用。当然,只有在两端都使用.NET时,此代码才有效。如果您有iOS或Android客户端,则需要使用与操作系统无关的压缩实用程序

您是否接受/返回WCF方法中的流参数?@DominicZukiewicz,该参数将不会被缓冲。您使用的是.net(托管内存环境)。如果要在.net中移动大块数据,需要分配大块内存。如果这些数据块是动态增长/分配的,那么您最终将对大量数据进行GCG和复制。我注意到,在大多数代码中,传递的是预期输出的长度。但是,我不确定某些框架代码中是否存在这种情况。另外,仅在包含代码的情况下,同一时间至少有3份相同数据的副本。发送文件总是一件麻烦事,因为现在您必须提高
maxStringContentLength
设置。您还会发现Base64实际上也比压缩版本大。@Aron我正在使用WCF将压缩文件从30英里以外的服务器传输到我的机器。我正在使用netTcpbindings来实现这一点。我认为问题不在于内存大小,因为我已经分配了足够大的缓冲区来处理3.7MB的内存。我也没有传递预期输出的长度。长度用于将文件从二进制转换为基64。这实际上已经足够快了。瓶颈在于数据的实际传输。感谢您的回复,但我仍在寻找答案。如果您使用的是.net 4.5,请打开net.tcp上的压缩。OP还提到使用net.tcp,因此使用.net。@Brian-是的,我两边都在使用.net4.0。非常感谢这个例子。明天如果时间允许,我会尝试一下,然后再给你回复。@阿伦,谢谢你的邀请suggestions@Brian-嗨,布莱恩,今天我使用了你提供的例行程序,看看这是否会缩短换乘时间。我想说声谢谢。你提供的课程做得很好。但是,对于2634 kb或2.6 mb的文件,传输速率为2分钟19秒。所以说实话,它丝毫没有改善时间。但是,尝试一下很有趣。我只是想知道如何在不到15秒的时间内将同一个文件上传到我的谷歌硬盘共享中。所以我会继续寻找。请随时欢迎任何其他建议-谢谢里克,我无法想象问题出在哪里。2分钟2 MB真的很慢。我在industrial size web services(WCF)fr上工作了一年多,可以轻松地在<2分钟内从主机到客户端或从客户端到主机交付1GB,而且不是WCF交付减慢了速度,而是加快了数据库和获取二进制文件的速度。所以我不知道该怎么建议你。如果我处在你的位置,我想我会尽力排除一切可能。例如,如果您在网络上运行/测试,我会尝试在同一台计算机上运行客户机/主机,从一个文件夹读取数据,然后写入另一个文件夹,以消除网络作为可能的瓶颈。如果这不起作用,我会尝试隔离交付的下一部分
byte[] binaryData;
System.IO.FileStream inFile;
inFile = new System.IO.FileStream(path2ZipFile,
             System.IO.FileMode.Open,
             System.IO.FileAccess.Read);
binaryData = new Byte[inFile.Length];
            long bytesRead = inFile.Read(binaryData, 0, (int)inFile.Length);
inFile.Close();
string convertedToBase64 = System.Convert.ToBase64String(binaryData, 0,
                           binaryData.Length);
handler(guest, zipFilename, convertedToBase64);
using System;
using System.IO;
using System.IO.Compression;
using System.Text;

namespace CompressString
{
internal static class StringCompressor
{
    /// <summary>
    /// Compresses the string.
    /// </summary>
    /// <param name="text">The text.</param>
    /// <returns></returns>
    public static string CompressString(string text)
    {
        byte[] buffer = Encoding.UTF8.GetBytes(text);
        var memoryStream = new MemoryStream();
        using (var gZipStream = new GZipStream(memoryStream, CompressionMode.Compress, true))
        {
            gZipStream.Write(buffer, 0, buffer.Length);
        }

        memoryStream.Position = 0;

        var compressedData = new byte[memoryStream.Length];
        memoryStream.Read(compressedData, 0, compressedData.Length);

        var gZipBuffer = new byte[compressedData.Length + 4];
        Buffer.BlockCopy(compressedData, 0, gZipBuffer, 4, compressedData.Length);
        Buffer.BlockCopy(BitConverter.GetBytes(buffer.Length), 0, gZipBuffer, 0, 4);
        return Convert.ToBase64String(gZipBuffer);
    }

    /// <summary>
    /// Decompresses the string.
    /// </summary>
    /// <param name="compressedText">The compressed text.</param>
    /// <returns></returns>
    public static string DecompressString(string compressedText)
    {
        byte[] gZipBuffer = Convert.FromBase64String(compressedText);
        using (var memoryStream = new MemoryStream())
        {
            int dataLength = BitConverter.ToInt32(gZipBuffer, 0);
            memoryStream.Write(gZipBuffer, 4, gZipBuffer.Length - 4);

            var buffer = new byte[dataLength];

            memoryStream.Position = 0;
            using (var gZipStream = new GZipStream(memoryStream, CompressionMode.Decompress))
            {
                gZipStream.Read(buffer, 0, buffer.Length);
            }

            return Encoding.UTF8.GetString(buffer);
        }
    }
}
}