Dynamic Resizing Of Buffer With ReceiveNetworkData
Posted: Thu Feb 08, 2007 1:09 pm
As you probably don't know how much data there is before you've received it it would be good if the buffer would just grow to the appropriate size.
http://www.purebasic.com
https://www.purebasic.fr/english/
Well both REALbasic and Hotbasic can do the impossible.Kaeru Gaman wrote:and it is simply impossible...
Well you can do it (yourself) with CopyMemory() and ReAllocateMemory() for example.the.weavster wrote:Well both REALbasic and Hotbasic can do the impossible.Kaeru Gaman wrote:and it is simply impossible...
Something like this ?the.weavster wrote:I tried doing it with ReallocateMemory() but it kept causing a crash.
Maybe I was doing it wrong, could you give me a code snippet?
Thanks
Weave
Code: Select all
Repeat
If NetworkClientEvent(ConnectionID) = #PB_NetworkEvent_Data
BytesRead = ReceiveNetworkData(ConnectionID, *NetworkDataBuffer, 5000)
If BytesRead > 0
*NewBuffer = ReAllocateMemory(*BigBuffer, TotalBytesRead + BytesRead)
If *NewBuffer
*BigBuffer = *NewBuffer
CopyMemory(*NetworkDataBuffer, *BigBuffer + TotalBytesRead, BytesRead)
TotalBytesRead + BytesRead
; /////////////////////////////////////////
; Test if end of data (depends on protocol)
If EndOfTransmission = #True
Debug "* BREAK (END)"
Break
EndIf
; /////////////////////////////////////////
Else
Debug "* BREAK (ReAllocate failed)"
Break
EndIf
EndIf
EndIf
ForEver
; All the data is in *BigBuffer (length = TotalBytesRead)
yes of course, but this will end upgnozal wrote:Well you can do it (yourself) with CopyMemory() and ReAllocateMemory() for example.the.weavster wrote:Well both REALbasic and Hotbasic can do the impossible.Kaeru Gaman wrote:and it is simply impossible...
Which is what you have to do with ReceiveNetworkData() becauseKaeru Gaman wrote:yes of course, but this will end up
- either
setting a huge buffer first
afaik network-data does not have a header describing the length of incoming data
Which is more like I was hoping to achieve.- or
starting with a small buffer and making it bigger while recieving,
wich will mean recieving really small packages.
Adventageous to what? What is your third alternative?both don't sound really advantageous to me...
Yes, why should PureBasic renounce this, while other languages have this feature?the.weavster wrote:Well both REALbasic and Hotbasic can do the impossible.
Code: Select all
Repeat
If NetworkClientEvent(ConnectionID) = #PB_NetworkEvent_Data
BytesRead = ReceiveNetworkData(ConnectionID, *NetworkDataBuffer, MaxBytes)
overruns = 0
While BytesRead = MaxBytes ; This means more data to be read
overruns + 1
*result = ReAllocateMemory(*NetworkDataBuffer, MaxBytes + MaxBytes * overruns)
If *result = *NetworkDataBuffer
; successfully enlarged the buffer
; reset the insertion point of the new larger buffer to past the already-read data
BytesRead = ReceiveNetworkData(ConnectionID, *NetworkDataBuffer + (MaxBytes + MaxBytes * (overruns-1)), MaxBytes)
Else
MessageRequester("OOPS!", "Insufficient memory to complete communication")
Break
EndIf
Wend
EndIf
ForEver
Sometimes I've noticed that BytesRead can actually be smaller than MaxBytes but still there is more data to be received! It's kinda weird/insane that the help file doesn't warn anyone about this. I found out that I have to include the packet size in a header and never stop reading until I got it all.netmaestro wrote:Code: Select all
BytesRead = ReceiveNetworkData(ConnectionID, *NetworkDataBuffer, MaxBytes) While BytesRead = MaxBytes ; This means more data to be read ... Wend
Code: Select all
// Receive until the peer closes the connection
do {
iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
if ( iResult > 0 )
printf("Bytes received: %d\n", iResult);
else if ( iResult == 0 )
printf("Connection closed\n");
else
printf("recv failed: %d\n", WSAGetLastError());
} while( iResult > 0 );
Code: Select all
Repeat
DataLength = ReceiveNetworkData(ServerID,*Buffer,BufferLength)
TotalSize + DataLength
Debug "recieving..."+Str(TotalSize)+" "+Str(DataLength)
Until DataLength = 0
Debug "done"
As you can see it never debugged "done", which means there is no way for me too see when it has received all the data. This code just hangs after it received the data.recieving...7504 7504
recieving...18760 11256
recieving...22512 3752
recieving...37520 15008
recieving...45024 7504
recieving...48776 3752
recieving...52528 3752
recieving...56280 3752
recieving...60032 3752
recieving...63784 3752
recieving...67536 3752
recieving...71288 3752
recieving...75040 3752
recieving...78792 3752
recieving...82544 3752
recieving...86296 3752
recieving...90048 3752
recieving...93800 3752
recieving...98688 4888
Code: Select all
Until DataLength <> BufferLength
(should be 98688)...
recieving...27000 1000
recieving...28000 1000
recieving...29000 1000
recieving...30000 1000
recieving...30660 660
done
What I start to understand is that this is how networks work (it can be unstable) and the help file should let us know.recieving...94000 2000
recieving...96000 2000
recieving...96360 360
recieving...98360 2000
recieving...98688 328