I'm trying to get an Image
from a WCF service.
I have an OperationContract
function that returns an Image
to the client, but when I call it from the client, I get this exception:
The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '00:00:59.9619978'.
Client:
private void btnNew_Click(object sender, EventArgs e)
{
picBox.Picture = client.GetScreenShot();
}
Service.cs:
public Image GetScreenShot()
{
Rectangle bounds = Screen.GetBounds(Point.Empty);
using (Bitmap bmp = new Bitmap(bounds.Width,bounds.Height))
{
using (Graphics g = Graphics.FromImage(bmp))
{
g.CopyFromScreen(Point.Empty, Point.Empty, bounds.Size);
}
using (MemoryStream ms = new MemoryStream())
{
bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
return Image.FromStream(ms);
}
}
}
IScreenShot
Interface:
[ServiceContract]
public interface IScreenShot
{
[OperationContract]
System.Drawing.Image GetScreenShot();
}
So why is this happening and how do I fix it?
I've figured it out.
TransferMode.Streamed
or StreamedResponse
(depends on your need).Stream.Postion = 0
so you start reading the stream from the beginning.In the service:
public Stream GetStream()
{
Rectangle bounds = Screen.GetBounds(Point.Empty);
using (Bitmap bmp = new Bitmap(bounds.Width, bounds.Height))
{
using (Graphics g = Graphics.FromImage(bmp))
{
g.CopyFromScreen(Point.Empty, Point.Empty, bounds.Size);
}
MemoryStream ms = new MemoryStream();
bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
ms.Position = 0; // This is very important
return ms;
}
}
Interface:
[ServiceContract]
public interface IScreenShot
{
[OperationContract]
Stream GetStream();
}
On the client side:
public partial class ScreenImage: Form
{
ScreenShotClient client;
public ScreenImage(string baseAddress)
{
InitializeComponent();
NetTcpBinding binding = new NetTcpBinding(SecurityMode.None);
binding.TransferMode = TransferMode.StreamedResponse;
binding.MaxReceivedMessageSize = 1024 * 1024 * 2;
client = new ScreenShotClient(binding, new EndpointAddress(baseAddress));
}
private void btnNew_Click(object sender, EventArgs e)
{
picBox.Image = Image.FromStream(client.GetStream());
}
}
You can use Stream to return large data/Images.
You will need to define something that is serializable. System.Drawing.Image
is, but not in the context of WCF (using DataContractSerializer
) by default. That could range from returning the raw bytes as an array, or serialization to a string (base64, JSON) or implementing a DataContract
that is serializable and can carry the data with it.
As others have said, WCF supports streaming, but that's not the crux of the issue here. Depending on the size of the data you might wish to do this, and doing so will reduce the problem in itself since you would be streaming bytes (from an evident, top-level view).
You could also take a look at this answer to help you get the at the actual exception details, like a full stacktrace instead of just the fault info.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.