[英]UDP Server and Client in Delphi
我正在制作UDP C / S. 我遇到服務器每秒可以接收的數據數量問題。
我已經測試過向服務器發送10,100,1000批數據消息,10,100沒有問題。 發送1000時,只收到300~400。 所有測試都在本地進行。
我嘗試使用ICS的twsocket和Synapse的tudpblocksocket來實現服務器。 兩者都出現了同樣的問題。
可以向我解釋為什么會發生這種情況,以及如何改善服務器性能。
使用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;
...
使用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不保證消息傳遞 - 如果緩沖區中沒有位置,則會毫不猶豫地丟棄數據包。 如果您需要有保證的交付,請使用TCP並在TCP之上構建基於消息的通信方案。 或者使用已有的MsgConnect產品。 十字軍的注意事項:MsgConnect有一個開源版本。
如果您想使用UDP協議並且不丟失任何數據包,則必須在程序中添加Acknowledge機制,因為UDP數據包在傳輸過程中可能會丟失。 這種ACK機制已經在TCP協議中實現,因此它是性能和一致性的最佳選擇。
如果你不能使用TCP(也許你的客戶端沒有足夠的CPU能力或RAM來處理TCP),可以考慮使用一些易於編碼的基於UDP的協議,如TFTP。 我們通過SynCrtUnit實現了TFTP客戶端和服務器,但是在Synapse中有這樣的組件。 但TFTP很慢,因為它等待每個傳輸數據包的ACK信號。 所以你不會丟失任何數據包,但與TCP相比,速度會很差。
去年,我在Delphi中實現了這樣的TFTP服務器,然后在基於DOS的自動引擎中實現了TP 7中的TFTP客戶端。 這工作得很好,一些對象結構在兩端共享。 TFTP / UDP / IP堆棧在純TP 7中編碼,只有靜態分配的內存,並且運行良好。
但是,如果您沒有這種“低CPU”要求,而是考慮使用TCP / IP而不是UDP / IP。 如果你需要一些廣播,那么使用UDP,但使用某種ACK機制。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.