举一个例子:
第一种网络情况,一台计算ping服务器返回500毫秒,但是中间不掉包,它可以在10秒中把服务器一批数据读出来
第二种网络情况,ping 服务器返回10毫秒(应该说比较上面快很多),但是ping的过程中偶尔会掉包,这样导致读取数据的时间竟然达30秒,有时就是读不出来这种原因,目前我猜想,是WCF传输跟传统的有点区别,它是整块传输的,如果在传输中间掉包,它又要从头重新传,它差不像socket分成小块传,所以导致WCF在网络不稳定情况的大块传输,很难成功想问一下,有没有解决方案,比如:WCF有什么设置,不是整块传输,可以断点续传之类的??

解决方案 »

  1.   

    理论上TCP/IP丢包是会自动重传的,所以应该不会很慢的。至于你所说的整块传输是缓存模式吧,数据大点的情况最好使用流模式传输,一段段获取数据,就算传输中有什么问题,也不需要整块重传,流传输是有断点功能的。
      

  2.   

    你把WCF用低级的逻辑来理解了。TCP本来就是把大包拆成成百上千的小包传输,然后才汇聚的。所以你对
    WCF的断言大概是玩底层概念时不小心造成的多心、缺乏测试。
      

  3.   

    我说的整块就是缓存模式,如果只是上传下载文件,用流传输,断点续传功能的确 不错。但是用得比较多的是大量dataset传输,这种用断点,好像不太会用
      

  4.   

    WCF内部是怎么传输被封装了,我太清楚,但是我上面的二种网络情况是存在的,我想知道是什么原因??
      

  5.   


    dataset也可以用流传输的,你不需要怎么设断点,你只要像平时一样用,它传输的时候会自动按照流传输的。话说对于数据量较大的dataset,还是用流传输更合适,因为那样就不需要在服务器端缓存一个较大的dataset副本了,客户端也不需要等到数据全部接收完毕才处理。网上有类似的WCF传输大数据DataSet的方案,我看过后感觉直接用流模式传输就可以了,效果更佳。如果说WCF的数据验证机制是错误后重传,那么缓存模式下的重传肯定是整个请求的重传,而流模式下的重传是有位置的重传,也就是每次发送的那段流数据重传,而不是整个流重传。最后重申一下,你不需要将DataSet转化为流,只要设置为流模式传输,所有数据自动转换为流进行传输的。
      

  6.   

    我想问一下:我目前后台,是先把Dataset压缩字节传输(5M能压到1M多,效果还是不错的,但是我发现缓冲占用一些时间),如果用流设置传输,是不是压缩后要好点呢,还是直接就dataset???
      

  7.   

    可以让WCF来边压缩边传输,没必要自己先压缩后传输,我记得我前面一个帖子不是给你看过一段示例代码吗?回想一下,里面是不是
    GZipMessageEncodingBindingElement compBindingElement = new GZipMessageEncodingBindingElement(new BinaryMessageEncodingBindingElement());
    这个就是在设置压缩传输,配合流模式就是压缩流啦这个压缩方式传输,MSDN上有示例代码的,可以直接拿来用,也可以修改下,你要是找不到我发给你也可以
      

  8.   

    你上次贴的代码,我调试不通过,有的是引用,有的可能是配置,但是给我的启发很大,我在网上找了一段代码,我自己又根据自己的需要修改了一下,如下:
    internal static class ChannelFactoryCreator
        {
            private static Hashtable channelFactories = new Hashtable();
            private static string ServerAddress;
            public static ChannelFactory<T> Create<T>(string ServerName)
            {
                if (string.IsNullOrEmpty(ServerName))
                {
                    throw new ArgumentNullException("ServerName");
                }            ChannelFactory<T> channelFactory = null;            if (channelFactories.ContainsKey(ServerName))
                {
                    channelFactory = channelFactories[ServerName] as ChannelFactory<T>;
                }            if (channelFactory == null)
                {
                    NetTcpBinding ntb = new NetTcpBinding();
                    ntb.Security.Mode = SecurityMode.None;
                    ntb.TransferMode = TransferMode.Streamed;
                    ntb.MaxBufferSize = 10240000;
                    ntb.MaxReceivedMessageSize = 10240000;
                    ntb.ReaderQuotas.MaxArrayLength = 10240000;
                    ntb.ReaderQuotas.MaxBytesPerRead = 10240000;
                    ntb.ReaderQuotas.MaxDepth = 20;
                    ntb.ReaderQuotas.MaxNameTableCharCount = 10240000;
                    ntb.ReaderQuotas.MaxStringContentLength = 10240000;
                    ntb.CloseTimeout = TimeSpan.Parse("00:10:00");
                    ntb.ReceiveTimeout = TimeSpan.Parse("00:10:00");
                    ntb.SendTimeout = TimeSpan.Parse("00:10:00");
                    ntb.OpenTimeout = TimeSpan.Parse("00:10:00");
                    if (string.IsNullOrEmpty(ServerAddress))
                    {
                        string filepath = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "\\config.xml";
                        XmlDocument XmlDoc = new XmlDocument();
                        XmlDoc.Load(filepath);
                        XmlNode xn = XmlDoc.SelectSingleNode("/ClientConfig/ServerInfoList/ServerInfo[@isSelected='1']");
                        ServerAddress = xn.Attributes["AddressAndPort"].Value.ToString();
                    }
                    EndpointAddress ea = new EndpointAddress("net.tcp://" + ServerAddress + ServerName);
                    channelFactory = new ChannelFactory<T>(ntb, ea);
                    lock (channelFactories.SyncRoot)
                    {
                        channelFactories[ServerName] = channelFactory;
                    }
                }            return channelFactory;
            }
        }
        public class ServiceRealProxy<T> : RealProxy
        {
            private string _ServerName;
            public ServiceRealProxy(string ServerName)
                : base(typeof(T))
            {
                if (string.IsNullOrEmpty(ServerName))
                {
                    throw new ArgumentNullException("ServerName");
                }
                this._ServerName = ServerName;
            }        public override IMessage Invoke(IMessage msg)
            {
                T channel = ChannelFactoryCreator.Create<T>(this._ServerName).CreateChannel();
                IMethodCallMessage methodCall = (IMethodCallMessage)msg;
                IMethodReturnMessage methodReturn = null;
                object[] copiedArgs = Array.CreateInstance(typeof(object), methodCall.Args.Length) as object[];
                methodCall.Args.CopyTo(copiedArgs, 0);
                try
                {
                    object returnValue = methodCall.MethodBase.Invoke(channel, copiedArgs);
                    methodReturn = new ReturnMessage(returnValue, copiedArgs, copiedArgs.Length, methodCall.LogicalCallContext, methodCall);
                    (channel as ICommunicationObject).Close();
                }
                catch (Exception ex)
                {
                    if (ex.InnerException is CommunicationException || ex.InnerException is TimeoutException)
                    {
                        (channel as ICommunicationObject).Abort();
                    }                if (ex.InnerException != null)
                    {
                        methodReturn = new ReturnMessage(ex.InnerException, methodCall);
                    }
                    else
                    {
                        methodReturn = new ReturnMessage(ex, methodCall);
                    }
                }            return methodReturn;
            }
        }
        public static class ServiceProxyFactory
        {
            public static T Create<T>(string ServerName)
            {
                if (string.IsNullOrEmpty(ServerName))
                {
                    throw new ArgumentNullException("ServerName");
                }
                return (T)(new ServiceRealProxy<T>(ServerName).GetTransparentProxy());
            }
        }    
    如果用自带的压缩在哪里修改?或者说在哪里插入一段代码?我前台不用配置文件,后台用配置文件
      

  9.   

    当然编译不过了,因为你少了个GZipEncoder.dll文件,那个系统自带的,是自己写的dll,微软有示例代码,提供了GZipEncoder.dll的开源代码,再根据需求自己修改。
    总的来说,你只要引用了GZipEncoder.dll,并且将NetTcpBinding 更换成CustomBinding就行了。因为只有CustomBinding才可以自定义BindingElement,而GZipMessageEncodingBindingElement 就是其中之一的BindingElement,引自GZipEncoder.dll。
      

  10.   

    靠,写错了一段:GZipEncoder.dll文件,那个不是系统自带的