I am making a UDP C/S. I am having a problem with number of data the server can receive per second.
I have tested sending batches of 10, 100, 1000 data messages to the server, 10, 100 received without a problem. when sending 1000, only 300 ~ 400 received. All tests done on locally.
I have tried implement the server using both ICS's twsocket and Synapse's tudpblocksocket. Both turned out with same problem above.
Could any explain to me why this happens, and how could I improve the server performance.
Code using TUDPBlockSocket
...
while not Terminated do
begin
try
sz := FUDPServer.WaitingData;
if sz > 0 then
begin
FUDPServer.RecvBuffer(mem.Memory, sz);
mem.Seek(0, 0);
AMessage := fFormats.ReadFromStream(mem);
DoMessageReceived(FUDPServer.RemoteSin.sin_addr, AMessage);
end;
finally
end;
end;
...
Code using ICS
...
procedure TShapeServer.WSocketDataAvailable(Sender: TObject; ErrCode: Word);
...
begin
SrcLen := SizeOf(Src);
stream := TMemoryStream.Create;
stream.SetSize(INT_BUFFER_SIZE);
Inc(fMessageReceived);
try
Len := FUDPServer.ReceiveFrom(stream.Memory, stream.size, Src, SrcLen);
if (FSenderAddr.S_addr = INADDR_ANY) or
(FSenderAddr.S_addr = Src.Sin_addr.S_addr) then
begin
while stream.Position < Len do
begin
try
AMessage := fFormats.ReadFromStream(stream);
DoMessageReceived(Src.Sin_addr, AMessage);
except
break;
end;
end;
end;
finally
stream.Free;
end;
end;
...
If you want to use UDP protocol and don't loose any packet, you'll have to add an Acknowledge mechanism to your program, because UDP packets can get lost during the transmission. This ACK mechanism is already implemented in the TCP protocol, so it's the best choice for performance and consistency.
If you can't use TCP (perhaps your client don't have enough CPU power or RAM to handle TCP), consider using some easy to code UDP based protocol, like TFTP. We implemented a TFTP client and server over our SynCrtUnit, but you have such a component in Synapse. But TFTP is slow, because it wait for an ACK signal for every transmitted packet. So you won't loose any packet, but the speed will be poor, compared to TCP.
Last year, I've implemented such TFTP Server in Delphi, then a TFTP Client in TP 7, in a DOS-based automated engine. This was working great, and some object structures were shared between both ends. The TFTP/UDP/IP stack was coded in pure TP 7, with only static allocated memory, and was working great.
But if you don't have such "low CPU" requirements, rather consider using TCP/IP instead of UDP/IP. If you need some broadcasting for example, then use UDP, but with some kind of ACK mechanism.
UDP doesn't guarantee message delivery - if there's no place in the buffer, the packet is dropped without hesitation. If you need guaranteed delivery, use TCP and build a message-based communication scheme on top of TCP. Or use our MsgConnect product which already has it. Note for crusaders: MsgConnect has an open-source version.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With