现在再尝试使用WCF传送文件!
虽然我知道可以使用流模型更好的实现,但现在我想尝试一下普通的方法
以下是我的服务端:using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.Xml;
using WCF_file_interfaces;
namespace WCF_file_Service
{
class Program : interfaces
{
static void Main(string[] args)
{
ServiceHost service = new ServiceHost(typeof(Program));
service.AddServiceEndpoint(typeof(interfaces),new NetTcpBinding(), "net.tcp://192.168.18.100:8000");
ServiceMetadataBehavior sm = new ServiceMetadataBehavior();
sm.HttpGetEnabled = true;
sm.HttpGetUrl = new Uri("http://192.168.18.100:8080");
service.Description.Behaviors.Add(sm);
service.Open();
Console.WriteLine("服务启动成功!");
while (true)
{
string r = Console.ReadLine();
if (r == "end")
break;
}
service.Close();
}
public bool file(byte[] by, string url)
{
FileStream fs = new FileStream(url,FileMode.CreateNew);
try
{
fs.Write(by, 0, by.Length - 1);
return true;
}
catch (Exception) { return false; }
finally { fs.Close(); }
}
}
}客户端:string fileurl;
private void button2_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
label1.Text = openFileDialog1.FileName;
fileurl = openFileDialog1.FileName;
}
} private void button1_Click(object sender, EventArgs e)
{
FileStream fs = new FileStream(fileurl, FileMode.Open);
byte[] by = new byte[fs.Length - 1];
fs.Read(by, 0, by.Length);
interfacesClient service = new interfacesClient();
try
{
service.Open();
bool OK = service.file(by, @"D:\1.txt");
if (OK == true)
MessageBox.Show("成功!");
else
MessageBox.Show("失败!");
}
catch (Exception ex) { MessageBox.Show(ex.Message,"client"); }
finally { service.Abort(); fs.Close(); }
}服务端配置文件:<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="NetTcpBinding_interfaces" 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="2147483647" maxBufferSize="2147483647" maxConnections="10"
maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="2147483647"
maxBytesPerRead="4096" maxNameTableCharCount="2147483647" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Transport">
<transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
<message clientCredentialType="Windows" />
</security>
</binding>
</netTcpBinding>
</bindings>
<client>
<endpoint address="net.tcp://192.168.18.100:8000/" binding="netTcpBinding"
bindingConfiguration="NetTcpBinding_interfaces" contract="ServiceReference_file.interfaces"
name="NetTcpBinding_interfaces">
<identity>
<userPrincipalName value="F5A6481BD70C427\Administrator" />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>再传送几K的数据的时候没问题,但是如果数据达到50K的时候就会出错:超出最大数组长度配额(16384),说可以修改maxArrayLength来增加配额,但我现在已经修改成2147483647了却还是不行?有查了下资料说还要同时修改客户端的配置文件,可是客户端的配置文件在哪?我怎么没找到?我只是对客户端程序进行了“填加服务引用”操作,然后生成了一个APP。CONFIG的配置文件,这个应该是服务端的还是客户端的呢?
求解答疑惑,谢谢!!!
虽然我知道可以使用流模型更好的实现,但现在我想尝试一下普通的方法
以下是我的服务端:using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.Xml;
using WCF_file_interfaces;
namespace WCF_file_Service
{
class Program : interfaces
{
static void Main(string[] args)
{
ServiceHost service = new ServiceHost(typeof(Program));
service.AddServiceEndpoint(typeof(interfaces),new NetTcpBinding(), "net.tcp://192.168.18.100:8000");
ServiceMetadataBehavior sm = new ServiceMetadataBehavior();
sm.HttpGetEnabled = true;
sm.HttpGetUrl = new Uri("http://192.168.18.100:8080");
service.Description.Behaviors.Add(sm);
service.Open();
Console.WriteLine("服务启动成功!");
while (true)
{
string r = Console.ReadLine();
if (r == "end")
break;
}
service.Close();
}
public bool file(byte[] by, string url)
{
FileStream fs = new FileStream(url,FileMode.CreateNew);
try
{
fs.Write(by, 0, by.Length - 1);
return true;
}
catch (Exception) { return false; }
finally { fs.Close(); }
}
}
}客户端:string fileurl;
private void button2_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
label1.Text = openFileDialog1.FileName;
fileurl = openFileDialog1.FileName;
}
} private void button1_Click(object sender, EventArgs e)
{
FileStream fs = new FileStream(fileurl, FileMode.Open);
byte[] by = new byte[fs.Length - 1];
fs.Read(by, 0, by.Length);
interfacesClient service = new interfacesClient();
try
{
service.Open();
bool OK = service.file(by, @"D:\1.txt");
if (OK == true)
MessageBox.Show("成功!");
else
MessageBox.Show("失败!");
}
catch (Exception ex) { MessageBox.Show(ex.Message,"client"); }
finally { service.Abort(); fs.Close(); }
}服务端配置文件:<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="NetTcpBinding_interfaces" 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="2147483647" maxBufferSize="2147483647" maxConnections="10"
maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="2147483647"
maxBytesPerRead="4096" maxNameTableCharCount="2147483647" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Transport">
<transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
<message clientCredentialType="Windows" />
</security>
</binding>
</netTcpBinding>
</bindings>
<client>
<endpoint address="net.tcp://192.168.18.100:8000/" binding="netTcpBinding"
bindingConfiguration="NetTcpBinding_interfaces" contract="ServiceReference_file.interfaces"
name="NetTcpBinding_interfaces">
<identity>
<userPrincipalName value="F5A6481BD70C427\Administrator" />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>再传送几K的数据的时候没问题,但是如果数据达到50K的时候就会出错:超出最大数组长度配额(16384),说可以修改maxArrayLength来增加配额,但我现在已经修改成2147483647了却还是不行?有查了下资料说还要同时修改客户端的配置文件,可是客户端的配置文件在哪?我怎么没找到?我只是对客户端程序进行了“填加服务引用”操作,然后生成了一个APP。CONFIG的配置文件,这个应该是服务端的还是客户端的呢?
求解答疑惑,谢谢!!!
解决方案 »
- 怎样才能实现页面间的传参啊?我怎么传的不好使?
- 怎么打印图片呢?
- left:1574,1575,1574,1575,1;center:9,8,求一个正则表达式
- 利用AJAX如何防止树对页面的刷新?
- 数据库里面有了新数据,winform怎么能知道呢? 不可能隔几十秒检索一下数据库吧????原问题:http://community.csdn.net/Expert/topic
- 100分求解:8bit编码的邮件如何解码?各位大大请帮忙
- mm急!在DataGrid中,获取指定的工作区的行?
- c# 写一个winform程序 实现功能:读取局域网中指定机器的文件
- 谁有c# how to program 或c#大学教程 完整无缺电子书
- 如何进行短信业务开发
- C#写的winform界面缩放问题
- 线程问题
客户端配置文件:
<readerQuotas maxDepth="32" maxStringContentLength="20971520" maxArrayLength="20971520" maxBytesPerRead="40960" maxNameTableCharCount="163840"/>maxBufferPoolSize="524288",从通道接收消息的最大缓存数量
maxBufferSize="65536" 从通道接收消息的缓存大小
maxConnections="10" 最大连接数目
maxReceivedMessageSize="65536">最大接收的消息大小
maxDepth="32" 最大节点深度
maxStringContentLength="8192" 最大内容长度
maxArrayLength="16384"最大数组长度
maxBytesPerRead="4096" 最大每次读取长度
maxNameTableCharCount="16384"最大NameTableChar的数量
IStreamed.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;using System.ServiceModel;
using System.IO;namespace WCF.ServiceLib.Message
{
/**//// <summary>
/// 消息契约(定义与 SOAP 消息相对应的强类型类)
/// </summary>
[MessageContract]
public class FileWrapper
{
/**//// <summary>
/// 指定数据成员为 SOAP 消息头
/// </summary>
[MessageHeader]
public string FilePath; /**//// <summary>
/// 指定将成员序列化为 SOAP 正文中的元素
/// </summary>
[MessageBodyMember]
public Stream FileData;
} /**//// <summary>
/// IStreamed接口
/// </summary>
[ServiceContract]
public interface IStreamed
{
/**//// <summary>
/// 上传文件
/// </summary>
/// <res>
/// 1、支持数据流传输的绑定有:BasicHttpBinding、NetTcpBinding 和 NetNamedPipeBinding
/// 2、流数据类型必须是可序列化的 Stream 或 MemoryStream
// /3、传递时消息体(Message Body)中不能包含其他数据,即参数中只能有一个System.ServiceModel.MessageBodyMember
/**//// </res>
/// <param name="fileWrapper">WCF.ServiceLib.Message.FileWrapper</param>
[OperationContract]
void UploadFile(FileWrapper fileWrapper);
}
}Streamed.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;using System.ServiceModel;
using System.IO;namespace WCF.ServiceLib.Message
{
/**//// <summary>
/// IStreamed类
/// </summary>
public class Streamed : IStreamed
{
/**//// <summary>
/// 上传文件
/// </summary>
/// <param name="fileWrapper">WCF.ServiceLib.Message.FileWrapper</param>
public void UploadFile(FileWrapper fileWrapper)
{
var sourceStream = fileWrapper.FileData; var targetStream = new FileStream(fileWrapper.FilePath,
FileMode.Create,
FileAccess.Write,
FileShare.None); var buffer = new byte[4096];
var count = 0; while ((count = sourceStream.Read(buffer, 0, buffer.Length)) > 0)
{
targetStream.Write(buffer, 0, count);
} targetStream.Close();
sourceStream.Close();
}
}
}
Streamed.cs
using (ServiceHost host = new ServiceHost(typeof(WCF.ServiceLib.Message.Streamed)))
{
host.Open(); Console.WriteLine("服务已启动(WCF.ServiceLib.Message.Streamed)");
Console.WriteLine("按<ENTER>停止服务");
Console.ReadLine();}
App.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<!--name - 提供服务的类名-->
<!--behaviorConfiguration - 指定相关的行为配置-->
<service name="WCF.ServiceLib.Message.Streamed" behaviorConfiguration="MessageBehavior">
<!--address - 服务地址-->
<!--binding - 通信方式-->
<!--contract - 服务契约-->
<!--bindingConfiguration - 指定相关的绑定配置-->
<endpoint address="Message/Streamed" binding="netTcpBinding" contract="WCF.ServiceLib.Message.IStreamed" bindingConfiguration="StreamedBindingConfiguration" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:12345/Message/Streamed/"/>
<add baseAddress="net.tcp://localhost:54321/"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MessageBehavior">
<!--httpGetEnabled - 使用get方式提供服务-->
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<netTcpBinding>
<!--transferMode - 指示通道是使用流处理模式还是缓冲模式来传输请求和响应消息-->
<!--maxReceivedMessageSize - 在采用此绑定配置的通道上可接收的最大消息大小(单位:字节)-->
<!--receiveTimeout - 在传输引发异常之前可用于完成读取操作的时间间隔-->
<binding name="StreamedBindingConfiguration" transferMode="Streamed" maxReceivedMessageSize="1073741824" receiveTimeout="00:10:00" />
</netTcpBinding>
</bindings>
</system.serviceModel>
</configuration>3、客户端
Streamed.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;using System.Windows.Forms;
using System.ServiceModel;
using System.IO;namespace Client2.Message
{
/**//// <summary>
/// 演示Message.Streamed的类
/// </summary>
public class Streamed
{
/**//// <summary>
/// 流数据上传文件
/// </summary>
/// <param name="source">源文件地址</param>
/// <param name="destination">目标路径</param>
public void HelloStreamed(string source, string destination)
{
try
{
var proxy = new MessageSvc.Streamed.StreamedClient(); var sr = new System.IO.FileStream(
source, System.IO.FileMode.Open); proxy.UploadFile(destination + Path.GetFileName(source), sr); sr.Close();
proxy.Close(); MessageBox.Show("上传成功");
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
}
}App.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<client>
<!--address - 服务地址-->
<!--binding - 通信方式-->
<!--contract - 服务契约-->
<endpoint address="net.tcp://localhost:54321/Message/Streamed" binding="netTcpBinding" contract="MessageSvc.Streamed.IStreamed" bindingConfiguration="StreamedBindingConfiguration" />
</client>
<bindings>
<netTcpBinding>
<!--transferMode - 指示通道是使用流处理模式还是缓冲模式来传输请求和响应消息-->
<!--sendTimeout - 在传输引发异常之前可用于完成写入操作的时间间隔-->
<binding name="StreamedBindingConfiguration" transferMode="Streamed" sendTimeout="00:10:00" />
</netTcpBinding>
</bindings>
</system.serviceModel>
</configuration>
service.AddServiceEndpoint(typeof(interfaces),new NetTcpBinding(), "net.tcp://192.168.18.100:8000");
你是新建了一个NetTcpBinding来使用,并没有指定它的任何属性,也就是说,你的NetTcpBinding是用了默认配置。正确的写法应该这样:NetTcpBinding netbinding = new NetTcpBinding();
netbinding.MaxBufferPoolSize = int.MaxValue;
netbinding.MaxBufferSize = int.MaxValue;
XmlDictionaryReaderQuotas readerQuotas = new XmlDictionaryReaderQuotas();
readerQuotas.MaxArrayLength = int.MaxValue;
readerQuotas.MaxStringContentLength = int.MaxValue;
readerQuotas.MaxBytesPerRead = int.MaxValue;
netbinding.ReaderQuotas = readerQuotas;
service.AddServiceEndpoint(typeof(interfaces),netbinding, "net.tcp://192.168.18.100:8000");
另外你给的APP.CONFIG文件是客户端的,你的服务器端并没有使用到配置文件。判断方法之一:看<client></client>标签。服务器端的是用<services></services>标签的。客户端只要修改配置文件即可,那个你自己改吧,应该没有问题的。
我已经对服务端做了如下设置:NetTcpBinding bin = new NetTcpBinding();
bin.ReceiveTimeout = new TimeSpan(10, 10, 10);
service.AddServiceEndpoint(typeof(interfaces), bin, "net.tcp://192.168.18.100:8000");但是却还是不行……
你仍旧配置错误,你这样是服务器端使用默认的缓存模式,客户端被你改为了流模式,出现了模式的不匹配,所以才会提示那个错误。另外,流模式下设置超时是没有意义的,因为不有超时的可能,流模式不支持会话,只能PerCall模式,没有会话就不会超时了。
服务端的正确的写法应该是这样:NetTcpBinding netbinding = new NetTcpBinding();
netbinding.MaxBufferPoolSize = int.MaxValue;
netbinding.MaxBufferSize = int.MaxValue;
netbinding.TransferMode = TransferMode.Streamed;//这里指定传输为流传输模式。
XmlDictionaryReaderQuotas readerQuotas = new XmlDictionaryReaderQuotas();
readerQuotas.MaxArrayLength = int.MaxValue;
readerQuotas.MaxStringContentLength = int.MaxValue;
readerQuotas.MaxBytesPerRead = int.MaxValue;
netbinding.ReaderQuotas = readerQuotas;
service.AddServiceEndpoint(typeof(interfaces),netbinding, "net.tcp://192.168.18.100:8000");
还是那句话,客户端你用的是配置文件,配置文件你应该会改的吧,我就不管那部分了。
http://www.cnblogs.com/qldsrx/
但还需要添加netbinding.MaxReceivedMessageSize = int.MaxValue;
否则会报MaxBufferSize 必须不能超过 MaxReceivedMessageSize异常,另外还需要引用using System.Runtime.Serialization;并且在引用中也要对System.Runtime.Serialization进行引用!
我的错误是不是你们都遇见过啊 具体怎么解决呢