16. oktober 2010 - 23:04Der er
27 kommentarer og 1 løsning
Vedvarende stream
Hej.
Er ved at lave noget ala. Remote Desktop i Visual Basic. Hver gang et nyt screen requestes åbnes en ny forbindelse. Det virker fint, men jeg ved gerne overføre i en vedvarende forbindelse, altså uden at skulle starte en ny.
Med andre ord vil jeg gerne signalere hvornår EOF forekommer, så modtageren kan modtage endnu en gang.
Her er hvad jeg har gjort indtil videre.
På senderens side: - Gem et screenshot i en MemoryStream - Overfør billedet - Send et signal for EOF, her er hvad jeg har gjort pt. ns.Write(BitConverter.GetBytes(-1), 0, 4) ns.Flush()
Modtageren tjekker så for EOF ved at tjekke om BitConverter.ToInt32(b, 0) = -1.
Det hele virker faktisk fint nok, men mit EOF-signalement når ikke altid frem til modtageren uden noget andet, hvilket resulterer i at der går yderligere tid.
Hvad skal jeg gøre for at signalere EOF, uden at lukke forbindelsen?
Første gang læste den længden, 1025, anden gang var længden meget høj og der opstod en exception. Har det noget med min java middle-man server at gøre, eller noget med buffersize? Alle buffer sizes er 1024, men den forsøger alligevel at sende en længde på 1025.
Modtager: Dim n As Integer = s.Read(b, 0, 1024) While (n > 0) Dim j As Integer = BitConverter.ToInt32(b, 0) If (j = -1) Then 'signalerer EOF Else mmStream.Write(b, 4, j) 'her opstår fejl eftr et par gange. End If n = s.Read(b, 0, 1024) End While
Sender: Dim readByte(1020 - 1) As Byte, n As Integer = ms.Read(readByte, 0, readByte.Length) While (n > 0) Dim sendByte(1024 - 1) As Byte Array.Copy(BitConverter.GetBytes(n), 0, sendByte, 0, 4) Array.Copy(readByte, 0, sendByte, 4, n) 'send bins.Write(sendByte, 0, sendByte.Length) bins.Flush() 'read next n = ms.Read(readByte, 0, readByte.Length) End While ms.Close() Dim endByte(1024) As Byte Array.Copy(BitConverter.GetBytes(-1), 0, endByte, 0, BitConverter.GetBytes(-1).Length) 'send endByte bins.Write(endByte, 0, 1024) bins.Flush()
Dim bn(4-1) As Byte s.Read(bn, 0, 4) Dim n As Integer = BitConverter.GetInt32(bn, 0, 4) Dim b() As Byte = New Byte(n) Dim ix As Integer = 0 Dim tmp As Integer While (tmp = s.Read(b, ix, b.Length - ix) > 0 ix = ix + tmp; End While
Det skal siges at længden af et chunk sendes med hvert chunk. Det overstående eksempel kunne godt ligne et eksempel på en længde af det hele der sendes først, men det skal jeg ikke kunne sige.
Du får lige noget kode, for den er gal igen. Den ser ud til at gå over den 'aftalte' størrelse.
Modtager: Dim frameSize As Integer = 0, sizeByte(4) As Byte If (s.Read(sizeByte, 0, 4) = 0) Then 'forbindelse lukket Return End If frameSize = BitConverter.ToInt32(sizeByte, 0) Dim n As Integer = s.Read(b, 0, 1024), downloaded As Integer = 0 Do Until downloaded = frameSize If (n = 0) Then Exit Do 'forbindelse lukket mmStream.Write(b, 0, n) downloaded += n n = s.Read(b, 0, 1024) Loop
Sender: bins.Write(BitConverter.GetBytes(ms.Length), 0, 4) bins.Flush() Dim readByte(1024) As Byte, n As Integer = ms.Read(readByte, 0, 1024) While (n > 0) 'write bins.Write(readByte, 0, n) bins.Flush() 'read next n = ms.Read(readByte, 0, 1024) End While
Med den metode får jeg en OutOfArray exception, fordi Math.Max(1024,frameSize-downloaded) = frameSize.
Lavede lige endnu en test, og den bliver ved med at læse forevigt, selvom klienten faktisk stopper med at sende før modtageren overhovedet har modtaget den 'aftalte' størrelse. Det virker meget underligt.
Dim n As Integer = s.Read(b, 0, Math.Min(1024, frameSize - mmStream.Length)) Do Until mmStream.ToArray().Length = frameSize If (n = 0) Then Exit Do 'forbindelse lukket mmStream.Write(b, 0, n) s.Read(b, 0, Math.Min(1024, frameSize - mmStream.Length)) Loop
Læser stadig videre.
Desuden stopper senderen ved omkring 40.000 bytes ved en frame der er 70.000 stor.
Første frame sendes nu uden problematik. Ved anden frame modtages en ugyldig størrelse, dvs. negativ eller forhøjet.
Sådan ser modtageren ud:
Dim b(1024 - 1) As Byte Dim frameSize As Integer = 0, sizeByte(4 - 1) As Byte If (s.Read(sizeByte, 0, sizeByte.Length) = 0) Then 'forbindelse lukket Return End If frameSize = BitConverter.ToInt32(sizeByte, 0) Dim n As Integer = s.Read(b, 0, Math.Min(b.Length, frameSize - mmStream.Length)) Do Until mmStream.Length >= frameSize If (n = 0) Then 'forbindelse lukket Return End If 'skriv mmStream.Write(b, 0, n) 'læs n = s.Read(b, 0, Math.Min(b.Length, frameSize - mmStream.Length)) Loop GoTo receiveFrameSize
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.