2012-05-14 168 views
4

林試圖從WCF服務的圖片
我有一個返回的圖片給客戶端,
但是當我從客戶 調用它,我得到這個異常的OperationContract的功能: 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'.返回圖像(WCF服務)

客戶:

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接口:

[ServiceContract] 
public interface IScreenShot 
{ 
    [OperationContract] 
    System.Drawing.Image GetScreenShot(); 
} 

所以這是爲什麼發生,如何解決呢?

+0

你可能想看看WCF [大數據和流(http://msdn.microsoft.com/en-us/library/ms733742.aspx)。 –

+0

@JoshuaDrake我以前讀過它,但我無法理解這一切,我只理解,如果我想傳輸大量數據,我應該使用流化代替緩衝。但是,它,我改變緩衝流,然後我得到了圖像? –

+0

你可以嘗試將圖像格式更改爲jpg而不是png。有時流png有問題。 – Rajesh

回答

6

我已經想通了。

  • 首先使用TransferMode.Streamed //或StreamedResponse取決於您的需要。
  • 返回流,並且不要忘記設置Stream.Postion = 0所以開始從開始讀取流。
在服務

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's a very important 
      return ms; 
     } 
    } 

接口:

[ServiceContract] 
public interface IScreenShot 
{ 
    [OperationContract] 
    Stream GetStream(); 
} 

在客戶端:

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()); 
    } 
} 
+1

對不起,我可以問你一個關於上面代碼的問題嗎?代碼行「img = Image.FromStream(ms);」是什麼? –

+0

@NguyễnHuy對不起,我沒有看到這個評論,直到現在,我忘了刪除它,現在是固定的 –

1

您將需要定義可序列化的內容。 System.Drawing.Image是,但默認情況下不在WCF的cotnext(使用DataContractSerializer)中。這可能包括將原始字節作爲數組返回,或者將序列化返回爲字符串(base64,JSON)或實現可序列化的DataContract,並且可以攜帶數據。

正如其他人所說,WCF支持流式傳輸,但這不是問題的關鍵。根據數據的大小,您可能希望這樣做,並且這樣做會減少問題本身,因爲您將流式傳輸字節(來自明顯的頂級視圖)。

您也可以take a look at this answer來幫助您獲得實際的異常詳細信息,例如完整的堆棧跟蹤,而不僅僅是故障信息。

+0

所以我需要聲明一個保存圖像並將其返回給客戶端的新類? –

+0

我會,或建議一個替代方案。我不會嘗試通過鉤子或騙子推下一個Image實例。 –

+0

我想避免使用套接字來接收圖像,我想以一種很好的方式返回它,你有一個好主意嗎? –