Delphi2010中DataSnap高级技术(6)—加强服务程序对访问者的控制能力

    技术2022-05-19  23

    原文出处:

    http://blog.csdn.net/sunstone/archive/2010/01/06/5145750.aspx

     

    1)作为一个服务程序,如果不限制客户端访问数量,后果将是很可怕的。如果有人恶搞,服务器不堪重负,内存将耗尽,最终服务器将宕机。如何限制访问者的数量呢?

    我们可以设置一个变量,来记录来访者的数量,如果超过我们既定的数字,那么后续的连接服务器请求,都将被断掉。

    2)限制了访问数量,但是如果不做密码身份认证,无关的人员也将能登陆服务器!解决办法是客户端传入用户名和密码,如果用户名和密码不正确,连接将被挂断。

    在客户端的SQLConnection1中driver分类的username和password属性设置好用户名和密码。

    3)尽量不要设置DSTCPServerTransport1的Maxthreads属性,还有数据库连接池也不要设置,delphi2010会有内存泄露,这两个参数保存默认即可。

    在dsserver1控件的onconnect事件中加入如下代码(使用的是tcp/ip连接):

    procedure TMainForm.DSServer1Connect  (DSConnectEventObject: TDSConnectEventObject);var  val: TCP_KeepAlive;  Ret: Integer;  ClientConnection: TIdTCPConnection;begin  // 最大连接数量,验证来访者密码  if (DSConnectEventObject.ChannelInfo = nil) or (Connections >= 500) or    (DSConnectEventObject.ConnectProperties[TDBXPropertyNames.UserName]      <> 'sunstone') or (DSConnectEventObject.ConnectProperties      [TDBXPropertyNames.Password] <> 'mypassword') then  begin    DSConnectEventObject.DbxConnection.Destroy;    // ClientConnection.Disconnect;  end  else  begin    // 获取socket连接    ClientConnection := TIdTCPConnection(DSConnectEventObject.ChannelInfo.Id);    ClientConnection.OnDisconnected := ClientDisconnectEvent;

        // 记录来访者数量    inc(Connections);    lblShowConnections.Caption := IntToStr(Connections);

        if Trim(ShowConnections.Cells[0, 1]) <> '' then      ShowConnections.RowCount := ShowConnections.RowCount + 1;

        ShowConnections.Cells[0, ShowConnections.RowCount - 1] := IntToStr      (DSConnectEventObject.ChannelInfo.Id);    ShowConnections.Cells[1, ShowConnections.RowCount - 1] :=      ClientConnection.Socket.Binding.PeerIP + ':' + IntToStr      (ClientConnection.Socket.Binding.PeerPort);    ShowConnections.Cells[2, ShowConnections.RowCount - 1] :=      DSConnectEventObject.ConnectProperties[TDBXPropertyNames.UserName];    ShowConnections.Cells[3, ShowConnections.RowCount - 1] :=      DSConnectEventObject.ConnectProperties[TDBXPropertyNames.Password];    ShowConnections.Cells[4, ShowConnections.RowCount - 1] := FormatDateTime      ('yyyy-mm-dd hh:nn:ss', Now);    // ShowConnections.Cells[6, ShowConnections.RowCount - 1] :=    // DSConnectEventObject.ConnectProperties    // [TDBXPropertyNames.ServerConnection];

        // 设置心跳包    val.OnOff := 1;    val.KeepAliveTime := 5000;    val.KeepAliveInterval := 1000;    WSAIoctl(ClientConnection.Socket.Binding.Handle, IOC_IN or IOC_VENDOR or 4,      @val, SizeOf(val), nil, 0, @Ret, nil, nil);  end;end;


    最新回复(0)