Allow controlling the networking library's "timeout"

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
Quin
Addict
Addict
Posts: 1131
Joined: Thu Mar 31, 2022 7:03 pm
Location: Colorado, United States
Contact:

Allow controlling the networking library's "timeout"

Post by Quin »

In my app, using the networking library, I have an interesting problem. I read until ReceiveNetworkData() returns -1 every time I get a #PB_NetworkEvent_Data event. However, with super long packets, this seemingly isn't always enough. It can be if the connection is fast enough. Conversely, the slower the connection, the more likely packet loss is. I'm assuming the internal library PB is using for networking has some built-in timeout that some connections just can't meet. It would be amazing if you let us customize this, maybe add an optional parameter to CreateNetworkServer() and OpenNetworkConnection.
Do keep in mind that my observations are just speculation based on months of trying to figure out why sometimes long packets just won't send despite me seemingly reading correctly, but it seems fairly likely to me at least.
User avatar
idle
Always Here
Always Here
Posts: 5840
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Allow controlling the networking library's "timeout"

Post by idle »

Hi Quin,

this is what I'm using in atomic web server, no problems sending large chunks
the -1 usually means a wouldblock meaning your sending to fast so when you get -1 delay and try again until either the payload is sent or your time out expires

Code: Select all

Procedure Atomic_Server_Send(*request.Atomic_Server_Request,*buffer,len,lock=1) 
  
  Protected  *atomic_server.Atomic_Server = *request\Serverid  
  Protected  *atomic_client.Atomic_Server_Client = *request\clientID 
  Protected outpos,trylen,sendlen
  
  Repeat
    
    trylen = len - outpos
    If trylen > *Atomic_Server\BufferSize
      trylen = *Atomic_Server\BufferSize
    EndIf
    
    Repeat 
      If TryLockMutex(*atomic_client\lock) 
        sendlen = SendNe1tworkData(*atomic_client\id, *Buffer+outpos, trylen)
        UnlockMutex(*atomic_client\lock)
        Break 
      Else  
        Delay(10) ;couldn't lock mutex try again 
      EndIf 
    Until ElapsedMilliseconds() > *atomic_client\timeout
    If sendlen > 0
      outpos + sendlen
      *atomic_client\timeout = ElapsedMilliseconds() + *atomic_server\timeout
    Else
      Delay(20) ; -1 so wait and try again 
    EndIf 
    If ElapsedMilliseconds() > *atomic_client\timeout
      Break    
    EndIf 
    Delay(1) ;for context switching 
  Until (outpos >= len Or *atomic_client\kill) 
  
EndProcedure   
since I'm only grabbing max of 64k this is sufficient

Code: Select all

Repeat
      FillMemory(*buffer,*Atomic_Server\BufferSize,0,#PB_Byte)
      Result = ReceiveNetworkData(ClientID, *Buffer, *Atomic_Server\BufferSize)
      If (result > 0 And MaxRequest < *Atomic_server\BufferSize)  
           Request + PeekS(*Buffer, Result, #PB_UTF8 | #PB_ByteLength)
           MaxRequest + result   
       Else 
          Delay(0) 
      EndIf   
  Until (Result <> *Atomic_Server\BufferSize)

Quin
Addict
Addict
Posts: 1131
Joined: Thu Mar 31, 2022 7:03 pm
Location: Colorado, United States
Contact:

Re: Allow controlling the networking library's "timeout"

Post by Quin »

Thanks a ton, Idle! I'll test this later today. What I'm currently having issues with is receiving, I assume this applies to the networking lib across-the-board?
User avatar
idle
Always Here
Always Here
Posts: 5840
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Allow controlling the networking library's "timeout"

Post by idle »

Quin wrote: Sun May 05, 2024 3:43 pm Thanks a ton, Idle! I'll test this later today. What I'm currently having issues with is receiving, I assume this applies to the networking lib across-the-board?
You can use a Similar pattern as the send with a timeout or check to see it any data was received

Code: Select all

ClientID = EventClient() 
Repeat
  FillMemory(*buffer,BufferSize,0,#PB_Byte)
  Result = ReceiveNetworkData(ClientID, *Buffer,BufferSize)
  If Result > 0 
    Request + PeekS(*Buffer, Result, #PB_UTF8 | #PB_ByteLength)
  Else 
    Delay(1) 
  EndIf   
Until Result <> BufferSize   
If result = -1 And Request = ""
  CloseNetworkConnection(ClientID) 
EndIf 

Post Reply