Donald Shimoda 0 Posted December 13, 2021 Cant find a sample code for this on all internet. Indy lost packages. Synapse work fine but not version for delphi linux yet. Share this post Link to post
Fr0sT.Brutal 900 Posted December 14, 2021 FWIW, with UDP packet loss is normal Share this post Link to post
Donald Shimoda 0 Posted December 14, 2021 7 hours ago, Fr0sT.Brutal said: FWIW, with UDP packet loss is normal In this case the device is connected with a direct cable and the response is ok. Synapse lost 0 data. Indy lost 20% of data. Share this post Link to post
Fr0sT.Brutal 900 Posted December 14, 2021 Probably there's something wrong in the way you use Indy or maybe an old version. Try to invite here @Remy Lebeau Share this post Link to post
Remy Lebeau 1393 Posted December 14, 2021 (edited) I agree with @Fr0sT.Brutal. UDP is an unreliable connectionless transport, so some amount of packet loss is to be expected, even over a direct cable. The most common cause of packet loss is when the receiver is reading packets slower than they are being sent and so it runs out of buffer space. Until buffer space is freed up, new packets will get silently discarded by the OS. So, check if your reading code is running too slow, or that your receive buffer is too small for your situation. Of course, there can be other causes of packet loss, too (network congestion, outages, etc). Edited December 15, 2021 by Remy Lebeau Share this post Link to post
Angus Robertson 574 Posted December 15, 2021 UDP application have to be designed to work around data loss, that is not the fault of a low level UDP component. If one loses packets and another does not, the first is probably less efficient. UDP is the basis of HTTP/3 and QUIC, which is reliable. Angus Share this post Link to post
Donald Shimoda 0 Posted December 18, 2021 (edited) On 12/14/2021 at 1:28 PM, Remy Lebeau said: So, either your reading code is running too slow, or your receive buffer is too small for your situation. The read is on a thread , nothing else interrupts. The same code, same test, using synapse work perfect. Problem in windows and Linux. Can send you the unit in private and maybe you can give your opinion? I doubt the problem is buffer because comm is text and small amount of data. Just to be sure: how to get a faster response on indy reception? How to define a bigger buffer? Thanks in advance Edited December 18, 2021 by Donald Shimoda Share this post Link to post
Donald Shimoda 0 Posted December 18, 2021 On 12/15/2021 at 4:00 AM, Angus Robertson said: If one loses packets and another does not, the first is probably less efficient Correct, i believe the same and this, maybe and i hope, can be fixed with small adjustments Share this post Link to post
irawan 2 Posted December 19, 2021 8 hours ago, Donald Shimoda said: Correct, i believe the same and this, maybe and i hope, can be fixed with small adjustments without any code, it is very difficult to help. choosing udp as protocol has it's own consequency, ready to handle packet loss. Share this post Link to post
Remy Lebeau 1393 Posted December 20, 2021 On 12/18/2021 at 11:09 AM, Donald Shimoda said: The read is on a thread , nothing else interrupts. Just because it runs is in a thread doesn't guarantee it is fast/efficient. And actually, in your scenario, there is actually an interrupt, see below... On 12/18/2021 at 11:09 AM, Donald Shimoda said: The same code, same test, using synapse work perfect. Problem in windows and Linux. Can send you the unit in private and maybe you can give your opinion? I just now gave it a quick look, and one major issue I see is that you are not using TIdUDPServer the way it is meant to be used, You are creating it in your own thread that does its own reading of the UDP socket, rather than using TIdUDPServer's OnUDPRead event. It seems you are not aware that TIdUDPServer is a multi-threaded component, its OnUDPRead event is fired in the context of internal reading threads, one per Binding. The Synapse/Net.TSocket UDP sockets you are using don't work that same way. So, it actually makes sense now why you are losing packets when using Indy - your code has multiple threads reading from the same UDP socket at the same time, so there are going to be times that you will receive packets in your own thread and be able to process them, and there are going to be times when TIdUDPServer will receive packets that you are ignoring. If you want to do your own reading of an Indy UDP socket, don't use TIdUDPServer, use TIdUDPClient instead. Despite their names, they are not truly client/server components, like with how TCP components work. Since UDP is connection-less, you can actually mix TIdUDPClient and TIdUDPServer in various ways. You can use TIdUDPServer as a client and TIdUDPClient as a server. Or you can have two TIdUDPClients, or two TIdUDPServers, communicate with each other. The difference between them is only in how they manage their respective sockets internally. With TIdUDPClient, it just creates the socket, but you are responsible for all of the reading/writing. With TIdUDPServer, it does all of the reading for you, and then you are responsible for writing. That being said, I see a secondary issue in your code, not related to any particular socket library, that could also cause packet loss. In your reading thread, when you do receive a packet, you lock a TCriticalSection before processing the packet. But, you are using TCriticalSection.TryLock() for that lock, which is not a blocking function. If, for some reason, the CS is already locked by another thread, TryLock() will exit immediate with a False return value, and you will then skip processing the packet, you are not caching/retrying the packet, you just throw it away. On 12/18/2021 at 11:09 AM, Donald Shimoda said: How to define a bigger buffer? There is actually 2 buffers involved - the kernel buffer inside the socket itself, and the application buffer that TIdUDPServer reads into before giving you the data in the OnUDPRead event. To set the size of the socket's buffer, you can use Indy's TIdSocketHandle.SetSockOpt() method to assign a value to the socket's SO_RCVBUF option. To set the size of the OnUDPRead buffer, TIdUDPServer has a BufferSize property, which defaults to 8K. Share this post Link to post
pcplayer99 11 Posted December 24, 2021 In Indy's document, it is said that you can not do any time consuming method in TIdUDPServer.OnRead procedure. to avoid TIdUDPServer loss package, I have added a buffer to receive data from TIdUDPServer.OnRead event. and then create another thread to handle data in this buffer. Share this post Link to post