gpt4 book ai didi

delphi - Indy,连接过多时访问冲突

转载 作者:行者123 更新时间:2023-12-03 18:32:34 26 4
gpt4 key购买 nike

我有三个问题:

  • 是否可以通过多个连接破坏IdTCPServer?
    我尝试测试我的应用程序,并且当我有多个连接时 - 它工作得很好(甚至几天),但是当有时连接数增加时,应用程序会导致访问冲突。我写的应用程序模拟 50 个不断发送数据的客户端(只有 sleep(200))。在这种情况下,IdTCPServer 会出现异常吗?
    我的应用程序通过 onExecute 事件从客户端接收信息并使用修改数据库表
    TidNotify 和 TIdSync 类。我相信它可以保护交叉连接线程?
    向客户端发送信息是由 TTimer 完成的(只是现在,我将其更改为其他线程)。
    我在这种情况下是否使用特殊保护或类似的东西就足够了:
    type
    PClient = ^TClient;
    TClient = record
    Activity_time:TDateTime;
    AContext: TIdContext;
    end;
    ...
    list := server.Contexts.LockList;
    try
    for i := 0 to list.Count - 1 do
    with TIdContext(list[i]) do
    begin

    if SecondsBetween(now(), PClient(data)^.activity_time) > 6 then
    begin
    Connection.IOHandler.Close;
    Continue;
    end;
    try
    Connection.IOHandler.writeln('E:');
    Except
    Connection.IOHandler.Close;
    end;
    end;
    finally
    server.Contexts.UnlockList;
    end;

  • 2.当服务器忙时拒绝连接是一种简单的方法(我认为我的数据库并不复杂(100行,只有一行被一个连接修改)但也许这是一种保持服务器稳定性的方法?

    3.我知道这个问题重复了很多次,但我没有找到满意的答案:如何保护应用程序以避免消息异常:“连接正常关闭”和“对等连接重置”?

    谢谢大家的建议

    最佳答案

    is it possible to destroy IdTCPServer by to many connection?



    你问错了问题,因为你实际上并没有破坏 TIdTCPServer本身,您只是从外部线程关闭空闲连接。这种逻辑可以(并且应该)在 OnExecute 内部处理。取而代之的是访问连接最安全的事件,例如:
    type
    PClient = ^TClient;
    TClient = record
    Activity_time: TDateTime;
    Heartbeat_time: TDateTime;
    AContext: TIdContext;
    end;

    procedure TForm1.serverConnect(AContext: TIdContext);
    var
    Client: PClient;
    begin
    New(Client);
    Client^.Activity_time := Now();
    Client^.Heartbeat_time := Client^.Activity_time;
    AContext.Data := TObject(Client);
    end;

    procedure TForm1.serverDisconnect(AContext: TIdContext);
    var
    Client: PClient;
    begin
    Client := PClient(AContext.Data);
    AContext.Data := nil;
    if Client <> nil then Dispose(Client);
    end;

    procedure TForm1.serverExecute(AContext: TIdContext);
    var
    Client: PClient;
    dtNow: TDateTime;
    begin
    Client := PClient(AContext.Data);
    dtNow := Now();

    if SecondsBetween(dtNow, Client^.Activity_time) > 6 then
    begin
    AContext.Connection.Disconnect;
    Exit;
    end;

    if SecondsBetween(dtNow, Client^.Heartbeat_time) > 2 then
    begin
    AContext.Connection.IOHandler.WriteLn('E:');
    Client^.Heartbeat_time := dtNow;
    end;

    if AContext.Connection.IOHandler.InputBufferIsEmpty then
    begin
    if not AContext.Connection.IOHandler.CheckForDataOnSource(100) then
    Exit;
    end;

    // process incoming data as needed ...

    Client^.Activity_time := Now();
    end;

    Is a simple way to refuse connection when server is to busy (I think my database isn't complicated (100 rows, only one row is modyfied by one connection) but maybe here is a way to keep stability of server?



    当前架构不允许拒绝接受连接。您可以让服务器正常接受连接,然后在需要时关闭接受的连接。您可以在 OnConnect 中执行此操作事件,或者您可以设置服务器的 MaxConnection属性设置为较低的非零数字,以允许服务器为您自动断开新连接,而不会浪费资源创建新 TIdContext对象和线程。

    另一种选择是调用服务器的 StopListening()服务器繁忙时的方法,使新连接无法再到达服务器,然后调用服务器的 StartListening()准备再次接受新客户时的方法。已经连接的现有客户端不应该受到影响,尽管我自己还没有真正尝试过。

    I know that this question was repeating many times but I didn't find satisfying answer: how to protect application to avoid message exception: "Connection closed gracefully" and "Connection reset by peer"?



    你不应该避免它们。让它们发生,它们是正常的错误。如果它们发生在服务器的事件内,只需让服务器为您正常处理它们。就是这样 TIdTCServer旨在使用。如果它们发生在服务器事件之外,例如在您的计时器中,那么只需将套接字操作包装在 try/except 中。阻止并继续前进。

    关于delphi - Indy,连接过多时访问冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14118050/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com