Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi中的UDP服务器和客户端_Delphi_Sockets_Udp - Fatal编程技术网

Delphi中的UDP服务器和客户端

Delphi中的UDP服务器和客户端,delphi,sockets,udp,Delphi,Sockets,Udp,我正在进行UDP C/S。服务器每秒可以接收的数据数量有问题 我已经测试过向服务器发送成批的10101000条数据消息,收到10100条没有问题。发送1000时,只接收到300~400。所有测试均在本地进行 我已经尝试使用ICS的twsocket和Synapse的tudpblocksocket来实现服务器。两人的问题都是一样的 请解释一下为什么会发生这种情况,以及如何提高服务器性能 使用TUDPBlockSocket的代码 使用ICS的代码 过程TShapeServer.WSocketDa

我正在进行UDP C/S。服务器每秒可以接收的数据数量有问题

我已经测试过向服务器发送成批的10101000条数据消息,收到10100条没有问题。发送1000时,只接收到300~400。所有测试均在本地进行

我已经尝试使用ICS的twsocket和Synapse的tudpblocksocket来实现服务器。两人的问题都是一样的

请解释一下为什么会发生这种情况,以及如何提高服务器性能

使用TUDPBlockSocket的代码

使用ICS的代码

过程TShapeServer.WSocketDataAvailable(发送方:TObject;错误代码:Word);
...
开始
SrcLen:=SizeOf(Src);
stream:=TMemoryStream.Create;
stream.SetSize(INT\u BUFFER\u SIZE);
公司(fMessageReceived);
尝试
Len:=FUDPServer.ReceiveFrom(stream.Memory,stream.size,Src,SrcLen);
如果(FSenderAddr.S_addr=INADDR_ANY)或
(FSenderAddr.S_addr=Src.Sin_addr.S_addr)然后
开始
而stream.Position
UDP不保证消息传递-如果缓冲区中没有位置,数据包将毫不犹豫地丢弃。
如果您需要有保证的交付,请使用TCP并在TCP之上构建基于消息的通信方案。或者使用我们已有的产品。十字军注意:MsgConnect有一个开源版本

如果要使用UDP协议且不丢失任何数据包,则必须向程序中添加确认机制,因为UDP数据包可能在传输过程中丢失。此ACK机制已经在TCP协议中实现,因此它是性能和一致性的最佳选择

如果您不能使用TCP(也许您的客户端没有足够的CPU功率或RAM来处理TCP),请考虑使用一些易于编码的基于UDP的协议,如TFTP。我们在我们的服务器上实现了一个TFTP客户机和服务器,但是Synapse中有这样一个组件。但TFTP速度很慢,因为它等待每个传输包的ACK信号。因此,您不会丢失任何数据包,但与TCP相比,速度会很差

去年,我在Delphi中实现了这样的TFTP服务器,然后在基于DOS的自动化引擎中实现了TP7中的TFTP客户端。这非常有效,一些对象结构在两端共享。TFTP/UDP/IP堆栈是在纯TP 7中编码的,只有静态分配的内存,并且工作得很好


<>但是如果你没有这样的“低CPU”的要求,而是考虑使用TCP/IP代替UDP/IP。例如,如果您需要一些广播,那么使用UDP,但使用某种ACK机制。

您可以使用wireshark(在Windows上它与winpcap一起工作)记录环回UDP通信吗?我还将研究Microsoft每秒数据包的“安全”限制。IIRC,tcpip.sys向事件登录报告了封顶操作。不确定是否做错了,但有回送适配器供我选择:(很棒的工具tho。那么,有没有办法使缓冲区变大,或者更快地处理缓冲区的内容?@Rob,原因是什么?即使你可以使缓冲区变大(而且你不能),你不能保证在较重的负载下缓冲区大小足够.在这种情况下,丢包将导致难以追踪错误.因此,最好不要使用"有缺陷"(为了这个具体目的) architecture@Darkerstar您是只为LAN还是为Internet开发应用程序?对于Internet,问题是每个路由器也有不同的缓冲区,数据丢失会更频繁地发生。@Darkerstar然后我建议您在投入更多时间到该体系结构之前立即进行性能测试。可能是这种丢失更严重ate在现实生活中是不可接受的。对于过分热心的垃圾邮件标记者来说:并不是每个指向营利性产品的链接都是垃圾邮件。这篇文章符合常见问题解答中提到的所有准则。谢谢,我一定会去看看。事实上,当你在保证交付的情况下构建基于UDP的通信时,很难提高TCP的速度:这是polis这是可能的(我们为某些特定任务和应用程序这样做),但非常重要。因此,在不活动的情况下使用TCP路由并可能断开连接可能是最好的方法。
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;
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;
...