using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.Runtime.Serialization;
using System.Reflection;
using System.IO;
namespace WcfDemo1
{
/// <summary>
/// 实现服务协定接口的服务类
/// </summary>
class Program
{
/// <summary>
/// 服务器端
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
// 服务器基址
Uri baseAddress = new Uri("http://localhost:1378/services");
// 声明服务器主机
using (ServiceHost host = new ServiceHost(typeof(MyService), baseAddress))
{
// 添加绑定和终结点
BasicHttpBinding binding = new BasicHttpBinding();
// 启用流模式
binding.TransferMode = TransferMode.StreamedRequest;
binding.MaxBufferSize = 1024;
// 接收消息的最大范围为500M
binding.MaxReceivedMessageSize = 500 * 1024 * 1024;
host.AddServiceEndpoint(typeof(IService), binding, "/test");
// 添加服务描述
host.Description.Behaviors.Add(new ServiceMetadataBehavior { HttpGetEnabled = true });
try
{
// 打开服务
host.Open();
Console.WriteLine("服务已启动。");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.ReadKey();
}
/* 备注
* 利用数据契约已经能够很好地完成数据的传输了,而数据契约只能控制消息体,
* 有时候我们想在数据传递过程中添加一些额外信息,而不希望添加额外的契约字段,
* 那么我们就得改消息报头,也就是说该使用消息契约了
* 消息契约第一个典型应用就是在执行文件传输时,文件的二进制信息放到body里,
* 而一些复加的文件信息则放在head里
*/
}
}
[ServiceContract(Namespace = "MyNamespace")]
public interface IService
{
[OperationContract]
ResultMessage UpLoadFile(TransferFileMessage tMsg);
}
public class MyService : IService
{
public ResultMessage UpLoadFile(TransferFileMessage tMsg)
{
ResultMessage rMsg = new ResultMessage();
if (tMsg == null || tMsg.File_Stream == null)
{
rMsg.ErrorMessage = "传入的参数无效。";
rMsg.IsSuccessed = false;
return rMsg;
}
try
{
using (FileStream outputStream = new FileStream(tMsg.File_Name, FileMode.OpenOrCreate, FileAccess.Write))
{
// 我们不用对两个流对象进行读写,只要复制流就OK
tMsg.File_Stream.CopyTo(outputStream);
outputStream.Flush();
rMsg.IsSuccessed = true;
Console.WriteLine("在{0}接收到客户端发送的流,已保存到{1}。", DateTime.Now.ToLongTimeString(), tMsg.File_Name);
}
}
catch (Exception ex)
{
rMsg.IsSuccessed = false;
rMsg.ErrorMessage = ex.Message;
}
return rMsg;
}
}
[MessageContract]
public class TransferFileMessage
{
[MessageHeader]
public string File_Name; //文件名
[MessageBodyMember]
public Stream File_Stream; //文件流
}
[MessageContract]
public class ResultMessage
{
[MessageHeader]
public string ErrorMessage;
[MessageBodyMember]
public bool IsSuccessed;
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Client
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnSelectFile_Click(object sender, EventArgs e)
{
OpenFileDialog dlg = new OpenFileDialog();
dlg.Filter = "MP3音频文件|*.mp3";
if (DialogResult.OK.Equals(dlg.ShowDialog()))
{
this.lbSelectedFilename.Text = dlg.FileName;
this.lbMessage.Text = "准备就绪。";
}
}
private async void btnTransfer_Click(object sender, EventArgs e)
{
//异步上传
if (!File.Exists(this.lbSelectedFilename.Text))
{
return;
}
FileStream fs = new FileStream(this.lbSelectedFilename.Text, FileMode.Open, FileAccess.Read);
WS.ServiceClient cl = new WS.ServiceClient();
this.btnTransfer.Enabled = false;
var response = await cl.UpLoadFileAsync(Path.GetFileName(this.lbSelectedFilename.Text), fs);
this.btnTransfer.Enabled = true;
if (response.IsSuccessed == true)
this.lbMessage.Text = "上传完成。";
else
this.lbMessage.Text = "错误信息:" + response.ErrorMessage;
}
}
}