• TServerSocket阻塞模式下RequestResponse编程框架


    Delphi6中的TServerSocket在线程阻塞模式(TThreadBlocking)下,OnRead/OnWrite事件的是在主线程中执行的,虽为多线程,实际效率不高。
    故我们若需要利用TServerSocket来开发真正多线程的服务器,则需要写TServerClientThread的子类,在这个子类中,自行处理数据的接收与发送,而重写的的重点在ClientExecute方法。下面为代码描述了这种编程思路。


    type
      TServerForm=class(TForm)
      ...
      private
        procedure  GetThread(Sender: TObject; ClientSocket: TServerClientWinSocket; var SocketThread: TServerClientThread);
      end;

    type
      TMyServerClientThread=class(TServerClientThread)
      private
        function WaitForData(TimeOut:Integer):Boolean;
      protected
        procedure ClientExecute;override;
      end;

    implementation

    { TMyServerClientThread }

    function TMyServerClientThread.WaitForData(TimeOut: Integer): Boolean;
    var
      FDSet:TFDSet;
      TimeVal:TTimeVal;
    begin
      FD_ZERO(FDSet);
      FD_SET(ClientSocket.SocketHandle,FDSet);
      TimeVal.tv_sec:=TimeOut div 1000;
      TimeVal.tv_usec:=TimeOut mod 1000;
      Result:=select(0,@FDSet,nil,nil,@TimeVal)>0
    end;

    procedure TMyServerClientThread.ClientExecute;
    var
      InputBuffer:TSockBuffer;
      iLen,iPos:Integer;
      sCmd:string;
      tmpBuf:string;
    begin
      InputBuffer:=TSockBuffer.Create;
      try
        while not Terminated and ClientSocket.Connected do
        begin
          if WaitForData(500) and not Terminated then
          begin
            iLen:=ClientSocket.ReceiveLength;
            if iLen=0 then
            begin
              Break
            end else
            begin
              SetLength(tmpBuf,iLen);
              ClientSocket.ReceiveBuf(tmpBuf[1],iLen);
              InputBuffer.WriteBuffer(tmpBuf[1],iLen);
              iPos:=InputBuffer.Pos(EOL);
              if iPos>0 then
              begin
                sCmd:=InputBuffer.Extract(iPos+1);
                Delete(sCmd,Length(sCmd)-1,2);
                if CmdList.IndexOf(sCmd)>-1 then
                  ClientSocket.SendText('+OK');
                if SameText(sCmd,'EXIT') then
                  Break;
              end;
            end;
          end;
        end;
      finally
        InputBuffer.Free;
      end;
    end;


    { TServerForm }

    procedure TServerForm.FormCreate(Sender: TObject);
    begin
      with TServerSocket.Create(Self) do
      begin
        Port:=4001;
        ServerType:=stThreadBlocking;
        OnGetThread:=GetThread; //这一步是关键,OnGetThread事件产生时,创建自己的线程。
        Active:=True;
      end;
    end;

    procedure TServerForm.GetThread(Sender: TObject;
      ClientSocket: TServerClientWinSocket;
      var SocketThread: TServerClientThread);
    begin
      SocketThread:=TMyServerClientThread.Create(False,ClientSocket);
    end;

  • 相关阅读:
    十四、linux内核裁剪
    十一、进程上下文
    五、进程间通信无名管道
    七、进程间通信信号
    react 中 CSS Modules 的简单使用(解决组件样式覆盖问题)
    react长列表性能优化 reactvirtualized
    vue+echarts绘制相应中国地图和省份地图
    vuex组件 vuexpersistedstate
    vue2 iview switch 使用render渲染,beforechange阻断前传参数
    Linux之crontab e定时任务
  • 原文地址:https://www.cnblogs.com/hnxxcxg/p/2940629.html
Copyright © 2020-2023  润新知