2013-04-12 60 views
4

Webclient用於向服務器上傳指令文件(高達1兆字節),並將該操作指令集作爲響應(最高1兆字節)接收爲二進制數據。雙向使用Webclient進行二進制

我能夠上傳二進制文件並下載二進制文件,但我無法使用相同的請求/響應命令執行此操作。意思是,不同的web客戶端可以做到這一點。在這種情況下,它會丟失對服務器上設置的流的引用。

Webclient bidirectional binary example

如何編寫和在一個單一序列讀取二進制數據?

服務器腳本

Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest 

      'Setup data reader 
      If cRead Is Nothing Then cRead = New ReadDataFromContext 
      cRead.Read(context) 'read data from 'context.Request.InputStream' 


      If cWrite Is Nothing Then cWrite = New WriteDataToContext 
      cWrite.Write(context) 'write data to 'context.Response.OutputStream' 


     End Sub 

Client類

Partial Public Class MainPage 
    Inherits UserControl 
    Private WithEvents WCUpload As WebClient 
    'Private WithEvents WCDownload As WebClient 
    Private Stream As IO.Stream 

    Dim U As New Uri("http://localhost:51001/communicator.ashx", UriKind.Absolute) 


    Public Sub New() 
     InitializeComponent() 
     WCUpload = New WebClient 
     'WCDownload = New WebClient 

    End Sub 

    Private Sub btnTest_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles btnTest.Click 
     WCUpload.OpenWriteAsync(U) 
    End Sub 


    'This methode is never called if using WCUpload (on WCDownload it works but WCDownload has no more data) 
    'Private Sub WC_OpenReadCompleted(sender As Object, e As System.Net.OpenReadCompletedEventArgs) Handles WCDownload.OpenReadCompleted 
    ' Dim D(e.Result.Length - 1) As Byte 
    ' e.Result.Read(D, 0, D.Length) 
    ' Me.btnTest.Content = System.Text.Encoding.UTF8.GetString(D, 0, D.Length) 
    'End Sub 

    Private Sub WC_OpenWriteCompleted(sender As Object, e As System.Net.OpenWriteCompletedEventArgs) Handles WCUpload.OpenWriteCompleted 
     Me.Stream = e.Result 

     Dim D() As Byte = System.Text.Encoding.UTF8.GetBytes("Hallo Timo") 
     Me.Stream.Write(D, 0, D.Length) 
     Me.Stream.Close() 
    End Sub 

    Private Sub WC_WriteStreamClosed(sender As Object, e As System.Net.WriteStreamClosedEventArgs) Handles WCUpload.WriteStreamClosed 
     'WC.OpenReadAsync(U) 

     'WCDownload.OpenReadAsync(U) 

     Me.Stream.Position = 0 '<<--- ERROR, cannot access to disposed object 
     Dim D(Me.Stream.Length - 1) As Byte 
     Me.Stream.Read(D, 0, D.Length) 
     Me.btnTest.Content = System.Text.Encoding.UTF8.GetString(D, 0, D.Length) 

    End Sub 

    Public Sub PushData(ByVal StreamIn As IO.Stream, ByVal StreamOut As IO.Stream) 
     Dim Buffer(4096 - 1) As Byte 
     Dim BytesRead As Integer 
     On Error Resume Next 

     'RaiseEvent Progress(Me, 0) 

     Do 
      BytesRead = StreamIn.Read(Buffer, 0, Buffer.Length) 
      If BytesRead <= 0 Then Exit Do 
      StreamOut.Write(Buffer, 0, BytesRead) 
      'RaiseEvent Progress(Me, StreamOut.Length/StreamIn.Length * 99) 'max 99 to raise the event with 100% 
     Loop 

     'RaiseEvent Progress(Me, 100) 
    End Sub 
End Class 
+0

當你說「相同的」請求/響應 - 你期待發送一連串的消息嗎?要麼...? –

+0

在服務器端,我需要「操作」數據。而不是在我需要用客戶端下載的服務器上創建新文件。只是在內存而不是文件系統中工作。也許我描述的不是很好,你可以解釋如何在不使用文件系統下載方法的情況下將操縱文件回傳給客戶端。只需要請求/響應而不更改網址。 – Nasenbaer

+0

「下載」與文件完全沒有關係。如果使用'UploadData'發送'byte []'並獲取'byte []'。這不是你需要的一切嗎? –

回答

2

這聽起來像你對我只是尋找UploadData方法,其中發送byte[]請求體到服務器,並返回一個byte[]響應體到客戶端。簡單:

byte[] req = ...; 
byte[] resp; 
using(var client = new WebClient()) { 
    resp = client.UploadData(address, req); 
} 

最終,HTTP是一個請求/響應協議 - 你可以順序地執行多個請求,雖然。如果你需要更多的靈活性,我建議你看看網絡套接字,它可以讓兩端發送臨時的。


有關Silverlight的異步使用,儘量的HttpClient的PCL版本 - 類似的API,但更全面執行比Silverlight提供開箱即用:http://blogs.msdn.com/b/bclteam/archive/2013/02/18/portable-httpclient-for-net-framework-and-windows-phone.aspx

+0

你能解釋你在哪裏找到UploadData嗎?還有如何管理這種異步? – Nasenbaer

+0

@Nasenbaer:http://msdn.microsoft.com/en-GB/library/system.net.webclient.uploaddata.aspx(和.NET 4.5中的UploadDataAsync。) –