简体   繁体   中英

UDP Server and Client in Delphi

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;
...

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 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM