webForumDet fria alternativet

Winsock Chunk?

.NET

7 svar · 452 visningar · startad av Thure

Medlem sedan okt. 200328 inlägg
Frågan#1

Nu är jag inne på min 35 timme så jag börjar bli lite seg i huvudet. Men är det någon som har en liten kodsnutt som kan hjälpa mig.
Problemet är att jag hämtar data från en server till en klient med winsock (vanlig text), och problemet är att jag tappar data pga att jag inte lyckas dela upp strängen i småbitar utan har varit tvungen att skicka hela strängen på en gång (jag vet att det inte ska gå) och strängen kan variera från 50 till 15 000 tecken. Och då tappar jag naturligtvis data. Har letat som en galning efter kod men inte lyckats hitta något vettigt, och jag lyckas inte använda samma metod som jag gör när jag skickar / tar emot filer, då jag använder "Byte" istället för "String". Någon som har en idé?

Medlem sedan juni 20022 599 inlägg
#2

Jag förstår inte alls vad du menar med att du "tappar data". Oavsett om paketen fragmenteras i avsändaränden därför att de är för stora så garanterar ju TCP att all data når mottagaren (och i rätt ordning). Om det är WinSock-kontrollen du använder så kommer du att få datan i flera på varandra följande DataArrival-events.

Kan du förklara närmare hur du menar?

Medlem sedan okt. 200328 inlägg
#3

I´m Back

Hej ursäkta dröjsmålet! Har varit i Åre en vecka.

Jag har rensat bort en del saker så det blir lättare för dig att se vad som händer, dock inget som han ställa till det problemet som jag har,så här ser det ut

Klienten

Public Sub Send()
If SockVar.Conn = False Then
Load WsFile(1)
WsFile(1).RemoteHost = SockVar.IP
WsFile(1).RemotePort = SockVar.Port
WsFile(1).Connect
SockVar.Conn = True
End If
End Sub

Private Sub WsFile_Connect(Index As Integer)

WsFile(1).SendData SockVar.SockUt
'Skickar ett värde som berättar för servern vad den
'ska returnera typ "31:"

End Sub

Private Sub WsFile_DataArrival(Index As Integer, ByVal bytesTotal As Long)

On Error Resume Next
WsFile(1).GetData SockVar.SockIn 

' datan som tas emot sparas i Sockvar.sockin

Unload WsFile(1)
SockVar.Conn = False

' används av en loop i en modul som väntar tills .Conn = false
End Sub

Servern:

Public Sub RecFile( Port As String)

    WsFile(0).LocalPort = Port
    WsFile(0).Listen
    iSock = 0

End Sub

Private Sub WsFile_ConnectionRequest(Index As Integer, ByVal requestID As Long)
iSock = iSock + 1
Load WsFile(iSock)
WsFile(iSock).Accept requestID

End Sub

Private Sub WsFile_DataArrival(Index As Integer, ByVal bytesTotal As Long)

Dim InData As String
Dim UtData As String

WsFile(Index).GetData InData
'Här får den då värdet som är t.ex "31:", och då hämtar den databasfält i en AccessDatabas, som den sen tabsepararar och skickar. Som sagt så kan det bli en hel de del data och beroende på om jag jobbar lokalt eller över nätverket så tappar den alla tecken som är över 8000 eller 15000.

UtData = "15.000 tecken"
WsFile(Index).SendData UtData

End Sub

Medlem sedan juni 20022 599 inlägg
#4

Jag kan läsa din kod, men jag förstår forfarande inte vad du menar med att du "tappar data". Menar du att du anser att en sändning måste motsvara en mottagning och att GetData SockVar.SockIn nödvändigtvis måste returnera hela sändningen? Isåf har du fel, du har ingen kontroll över hur paket fragmenteras på vägen.

Vad du måste göra är att klippa på ett avslutande tecken i din Senddata och sen fortsätta att bygga på SockVar.SockIn i flera events till du ser att du fått avslutningstecknet.

Medlem sedan okt. 200328 inlägg
#5

Detta är inte sant!!!!

Jag har laggt precis hela dagen på att lösa det här problemet.
Lade jag till ett tecken efter senddata (typ & ";" ) så kraschar VB när jag kör det. Under getdata så la jag en if sats där den hämtade det sista tecknet i den buffrade strängen (det niko förklarade som "bygga på SockVar.SockIn". Det funkar klockrent om stängen inte är längre än den var när jag körde den som i kodsnutten jag skickade igår, men när den blir större (vilket detta borde avhjälpa) så krashar som sagt VB.
En sak som jag funderat över är att om har det som jag hade det, så får jag upp det första "fragmentet" av sändingen och inte det sista, som jag logiskt sett borde ha fått.
Snart konverterar jag till trädgårdsmästare eller något annat utan datorskärm........´
Har inte lyckats hitta något vettigt på nätet heller om detta, bara newbieguider om hur du gör enkla chatter å sånt.
Nån som har en vettig länk som kan hjälpa mig eller fler tips?

Tack på förhand

Rickard

Medlem sedan juni 20022 599 inlägg
#6

Det funkar klockrent om stängen inte är längre än den var när jag körde den som i kodsnutten jag skickade igår, men när den blir större (vilket detta borde avhjälpa) så krashar som sagt VB.

Varför den skulle krascha vet jag inte riktigt. Men det beror väl knappast på datalängden? VB-strängar klarar mångdubbelt mycket mer data än det du verkar skicka ..

En sak som jag funderat över är att om har det som jag hade det, så får jag upp det första "fragmentet" av sändingen och inte det sista, som jag logiskt sett borde ha fått.

Nej, varför det? Du stänger ju socketen efter första mottagningen, vilket iofs borde ge ett fel i den sändande änden. Men du kanske har ett "on error resume next" någonstans.

Förslag:

- Stäng inte socketen i den mottagande änden. Det är sändarens uppgift.
- Använd ett avskiljartecken (som inte får finnas i datan) för att markera slutet på paketet.
- Undvik "on error resume next" så att du kan se vad som händer.
- Buffra inkommande data i mottagaren tills du får avskiljartecknet.

Så här brukar jag göra:

Public Const PAKET_AVGRANSARE As Long = 3

....

Private Sub WsFile_DataArrival(Index As Integer, ByVal bytesTotal As Long)
	Dim strSent As String
	Static sTrail As String
	Dim sPackets() As String
	strSent = Space(bytesTotal)
	WsFile(1).GetData strSent, bytesTotal
              sPackets = Split(strSent, Chr$(PAKET_AVGRANSARE))
              sPackets(0) = sTrail & sPackets(0) 
              For i = 0 To UBound(sPackets) - 1
            		'Hantera sPackets(i) (UtData) här
              Next i
             sTrail = sPackets(UBound(sPackets)) 
End Sub

...

WsFile(Index).SendData UtData & Chr$(PAKET_AVGRANSARE)

sTrail är en buffert som håller datan tills ett (eller flera) Chr$(PAKET_AVGRANSARE) dyker upp. (Sen behöver du så klart nån form av felhantering också.)

Medlem sedan okt. 200328 inlägg
#7

- Stäng inte socketen i den mottagande änden. Det är sändarens uppgift.
Den strängen räddade hela helgen för mig. Det är märkligt, sitter man och stirrar på samma kodsnutt för länge, så gör man tillslut bara samma ändringar om och om igen. (Jag iaf). Så jag får tacka dig så mycket niko, och är du i Blekinge nån dag så bjuder jag på lunch. Ha en fortsatt trevlig helg.

Rickard

Medlem sedan juni 20022 599 inlägg
#8

Ha en fortsatt trevlig helg.

Det hade jag. Bra att det ordnade sig.

255 ms totalt · 4 externa anrop · v20260731065814-full.e96017d9
120 ms — deklarationer (db)
0 ms — hämta statistik (cache)
132 ms — hämta tråd, inlägg och bilagor (db)
120 ms — ändringar (db)