双向使用Webclient进行二进制

时间:2013-04-12 21:55:59

标签: asp.net .net silverlight httpwebrequest webclient

Webclient用于将指令文件(最多1兆字节)上传到服务器,并将此操纵指令集作为响应(最多1兆字节)接收为二进制数据。

我能够上传二进制文件并下载二进制文件,但我无法使用相同的请求/响应命令。手段,不是相同的webclient可以做到这一点。在这种情况下,它将丢失对服务器上设置的流的引用。

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

客户端类

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

1 个答案:

答案 0 :(得分:2)

听起来我只是在寻找UploadData方法,该方法向服务器发送byte[]请求主体,并向客户端返回byte[]响应主体。简单如下:

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

最终,http是一个请求/响应协议 - 您可以按顺序执行多个请求。如果你需要更多的灵活性,我建议你看一下web-socket,它允许两端发送ad-hoc。


对于Silverlight上的异步使用,请尝试使用PCL版本的HttpClient - 类似的api,但比Silverlight提供更全面的实现:http://blogs.msdn.com/b/bclteam/archive/2013/02/18/portable-httpclient-for-net-framework-and-windows-phone.aspx