Toon posts:

[VB6 -> .NET] Binarydata over sockets komt niet aan in .NET

Pagina: 1
Acties:

Verwijderd

Topicstarter
De applicatie die ik aan het ontwikkelen ben, verstuurd een file van een VB6 applicaties over sockets naar een .NET applicatie.
Het probleem is echter dat de .NET applicatie de data pas gaat parsen op het moment dat ik de verbinding van de VB6 applicatie sluit.


Stuk VB6 code die de file verstuurt:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
    ' Open the file that we're sending, for BINARY mode. This means that we can
    ' read out bits regardless of what's in the file (text, image, music etc..).
    hFile = FreeFile
    Open strFilePath For Binary As #hFile
    
    ' We need to read the next unsent piece of the file, so move through the
    ' file past all the bits we've already sent. Then, when we read into
    ' strData, the data will be the next consecutive bytes.
    If (lngFilePos = 0) Then lngFilePos = 1
    Seek hFile, lngFilePos
    
    ' Work out how large this chunk is going to be. Normally, it will be the
    ' standard CHUNK_SIZE, but if the last piece is less than that, decrease it.
    lngChunkSize = LOF(hFile) + 1 - lngFilePos
    If (lngChunkSize > CHUNK_SIZE) Then lngChunkSize = CHUNK_SIZE
    
    ' If the chunksize was 0, it means there's no data left to send, so our
    ' transfer is complete.
    If (lngChunkSize = 0) Then
       ' Send the EOF marker so the remote host knows that's all the data.
       strData = "EOF" & vbNewLine
    Else
       ' Grab the data from the file, and increment our file pointer so that next
       ' time we read, we are reading the next piece of the file.
       strData = String$(lngChunkSize, 0)
       Get #hFile, , strData
       lngFilePos = lngFilePos + lngChunkSize
    End If
    
    'send the data to the server
    Call objServerSocket.SendData(strData)
    DoEvents
    
    'close the file we where reading from.
    Close #hFile



Stuk .NET code
code:
1
2
3
    int ChunkBytesSize = 3072;
    BinaryReader StreamReader;
    byte[] receivedBytes = StreamReader.ReadBytes(ChunkBytesSize);



Moet de data die verstuurd wordt vanuit VB geterminate worden ofzo?
Iemand enig idee wat het probleem kan zijn?

  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 09:50

pjvandesande

GC.Collect(head);

Hij wacht totdat er 3072 bytes zijn ontvangen of de stream is gesloten. Stuur jij wel 3072 bytes?

Verwijderd

Topicstarter
Nee ik stuur blijkbaar maar iets van 2000 bytes. Hoe kan ik ervoor zorgen dat ik ook data ontvang als er minder verstuurd wordt dan die 3072 bytes?

  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 09:50

pjvandesande

GC.Collect(head);

Ik heb het eerlijk gezecht nooit met een stream gedaan. Ik gebruik altijd Socket.Read en lees dan in chunks van 1024 bytes. Mocht het minder zijn omdat echt de package is afgelopen dan stopt hij eerder en returned de received bytes.

Kijk hier anders is naar.

Verwijderd

Topicstarter
Dat ga ik even proberen. Nu vraag ik me af wat nu precies het voordeel is van de 'stream' methode ipv direct de data uit de socket te halen?

  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 09:50

pjvandesande

GC.Collect(head);

Niets, het heeft geen voordelen. De socket zelf is eigelijk ook niets anders dan een Stream. Een StreamReader is meer een hulpmiddel.

  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 09:50

pjvandesande

GC.Collect(head);

Het is trouwens socket.Receive(), je kan hier ook een timeout instellen. Niet in de method zelf maar met socket.SetPropertie() oid.

Verwijderd

Topicstarter
Had al gevonden dat het Socket.Receive() was. Thnx.

  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 09:50

pjvandesande

GC.Collect(head);

Werkt het nu ook prima?

Verwijderd

Topicstarter
Werkt goed afgezien van 1 probleem.
Het eerste stuk data wat ik ontvang van de VB6 client is 2048 bytes ipv 3072 bytes groot.
Hierdoor ontbreekt structureel die eerste kiloByte aan een file.
Na de eerste set met data die verstuurd is, krijg ik gewoon blokken van 3072 binnen (afgezien van het laatste stukje natuurlijk).

code:
1
2
3
4
5
6
Byte[] FileDataBytes = new Byte[ChunkBytesSize];
int receivedBytes = _socket.Receive(FileDataBytes, FileDataBytes.Length, SocketFlags.None);

if (receivedBytes > 0) {
    //code dat de bytes in een file stored en de receivedBytes waarde naar een logfile schrijft
}


De VB6 client verstuurd wel die eerste kilobyte, heb ik getest door een VB6 server te schrijven.
Deze ontvangt het bestand zonder problemen.
Zit er al aan te denken om maar op marktplaats.nl te kijken of ik daar niet ergens goedkoop een kiloByte op de kop kan tikken :)

  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 09:50

pjvandesande

GC.Collect(head);

De blokken maken toch niet veel uit, want je weet hoeveel bytes je ontvangen heb. Daar moet je vanuitgaan en niet van je buffer size (FileDataBytes.Lenght).

Of snap ik nu even je probleem niet? :/

Verwijderd

Topicstarter
In de variable 'receivedBytes' staat hoeveel bytes aan data ik ontvangen heb.
Als ik deze waarde naar een logfile schrijf, zou hier moeten staan.

3072
3072
3072
1085 (deze is lager ivm einde van file)

Wat er in plaats daarvan gebeurt is:

2048
3072
3072
1085 (deze is lager ivm einde van file)

Dit terwijl de VB applicatie wel die eerste 3072 bytes verstuurt.

  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 09:50

pjvandesande

GC.Collect(head);

Als je naar je data zelf kijkt mis je het dus ook echt, dus het lijkt wel verloren te gaan ergens. Kun je in VB opvragen hoeveel bytes er zijn verzonden? Dit zou je met elkaar moet kunnen vergelijken.

Pak is een anderen buffersize. Dus probeer het is met een buffer van 512 bytes ofzo. Maakt dit enig verschil?

Verwijderd

Topicstarter
Ik heb verschillende buffer grotes ingesteld. Met het volgende resultaat:

1024
2048
2048
etc.
etc.
1085

Als ik een buffer neem die kleiner is dan 1024 dan is ontvangt de .NET app niets..
Bijzonder vreemd.

Verwijderd

Topicstarter
Ik heb het probleem nu opgelost met een vreselijke hack.
Vanuit de VB client stuur ik tijdens het versturen van het eerste block, een fake stuk data van 1024 bytes mee.
De .NET server raakt deze dus kwijt en ontvangt vervolgens wel de hele file zoals het hoort.
Als iemand een andere oplossing weet dan houd ik me aannbevolen want dit is echt niets zo.

  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 09:50

pjvandesande

GC.Collect(head);

Doe je ergens ander een socket of stream recieve/read method? Want met deze ransige oplossing beginnen mijn handen te juiken om jou het hele /14 door te slingeren :+

Maak is snel een .NET app en stuur is even wat fake data om te kijken of die bytes wel aankomen. De test app kan natuurlijk ook wel een vb app zijn.

Verwijderd

Topicstarter
Ik doe alleen een "streamReader.EndOfStream" check maar dat zou niets uit moeten maken zou je zeggen? Ik ga morgen even een test app maken zodat dit fatsoenlijk opgelost kan worden.
Schaam me dood voor deze oplossing :)

  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 09:50

pjvandesande

GC.Collect(head);

Haal je alles nu binnen via een StreamReader of via de socket.Receive method?

* pjvandesande is blij dan -NW een anderen oplossing gaat zoeken. :)

Verwijderd

Topicstarter
Via de socket.receive methode.

  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 09:50

pjvandesande

GC.Collect(head);

En waar gebruik je dan streamRead.EndOfStream?

Verwijderd

Topicstarter
Voordat ik de socket.receive aanroep.
Ik zit in een loop, bovenaan deze loop wordt altijd gecontroleerd of streamRead.EndOfStream is.
Als dat het geval is, dan is de client gedisconnect en gaan we uit de loop.
Als we niet streamRead.EndOfStream zijn, dan gaan we socket.receive uitvoeren.

  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 09:50

pjvandesande

GC.Collect(head);

Dan kun je beter de Poll method gebruiken van het Socket object.

Volgens mij geen EndOfStream geen garantie dat er ook data is. Dus een Poll lijkt mij sowieso beter. Socket.Connected word ook veel gebruikt, maar dit geeft ook geen garantie voor available data.

edit:

Wat toegevoegd.

[ Voor 37% gewijzigd door pjvandesande op 05-01-2005 09:58 ]

Pagina: 1