Page 1 of 1

Allow controlling the networking library's "timeout"

Posted: Sat May 04, 2024 11:46 pm
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.

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

Posted: Sun May 05, 2024 1:44 am
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)


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

Posted: Sun May 05, 2024 3:43 pm
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?

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

Posted: Sun May 05, 2024 11:41 pm
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