Foz wrote:Forgive my misunderstanding, but how would you know how much you will be receiving before you receive it?
Sometimes you do. Lets say a server runs a certain protocol and I send it a command and I KNOW that whatever data it replies to that command must be 128 bytes long (for example). But some servers choose to split that data up in several packets, then it makes sense to me to have a command which waits until it got it all.
In fact, these small changes to the receive function would make PureBasic very powerful for network programming! Powerful because of how simple it could interact with servers!
Right now we have to manually check each time before using ReceiveNetworkData that there actually is data to be received, if not the program will
hang forever if there was no data (which is silly). So the timeout part is also important in my opinion.
I made it myself now (to be used in clients):
Client:
Code: Select all
EnableExplicit
Procedure.l clientReceiveData(serverID,*buffer,bufferSize,timeout=1000,bytesToReceive=0)
;Will wait until received bytesToReceive or it times out.
;If bytesToReceive = 0 it will wait until the first packet is received or timeout.
;If return value is less than bytesToReceive it means that was all it received before timeout.
;If it receives more than bytesToReceive it will return the number of bytes received.
Protected dataLength, totalData, time
If bytesToReceive > bufferSize
totalData = -1 ;return error
Else
Repeat
Delay(10): time + 10
If NetworkClientEvent(serverID) = #PB_NetworkEvent_Data
dataLength = ReceiveNetworkData(serverId,*buffer+totalData,bufferSize-totalData)
If dataLength > -1
totalData + dataLength
time = 0 ;reset timeout each time we receive data
EndIf
EndIf
Until time >= timeout Or (bytesToReceive=0 And totalData>0) Or (bytesToReceive>0 And totalData>=bytesToReceive)
EndIf
ProcedureReturn totalData
EndProcedure
InitNetwork()
Define serverId, *buffer, bufferSize = 1000
serverId = OpenNetworkConnection("localhost",1000)
If serverId
*buffer = AllocateMemory(bufferSize)
Debug clientReceiveData(serverId,*buffer,bufferSize,1000,100)
Else
Debug "error"
EndIf
Server (to test with):
Code: Select all
EnableExplicit
Define *buffer = AllocateMemory(10000)
InitNetwork()
If CreateNetworkServer(0,1000)
Repeat
Select NetworkServerEvent()
Case #PB_NetworkEvent_Connect
SendNetworkData(EventClient(),*buffer,10)
Delay(100)
SendNetworkData(EventClient(),*buffer,83)
Delay(200)
SendNetworkData(EventClient(),*buffer,7)
Delay(900)
SendNetworkData(EventClient(),*buffer,6000)
EndSelect
ForEver
Else
Debug "error"
EndIf
But still it would be best if this was handled by the PureBasic function I think, because sometimes this might not cooperate with your code, especially on the server side using "NetworkServerEvent" in the receive code might cause troubles.