TServerSocket阻塞线程单元,希望对你有所帮助。需要注意的是: 1、如果你使用TServerSocket的stNonBlocking模式,重写TServerClientThread线程时要重载 TServerClientThread的ClientExecute过程,写你自己的处理过程; 2、如果在线程内部调用外部的过程,建议使用同步化方法; 3、线程访问线程内部变量的速度远远高于线程访问线程内部变量的速度 如果有问题的话,可以和我联系 Email: [email protected]
//********************************************************************************** //说明: TServerSocket阻塞线程 //作者: licwing 时间: 2001-4-21 //Email: [email protected] //********************************************************************************** unit BlockThread;
interface
uses SysUtils, Windows, Messages, Classes, ScktComp,ProxyCnt;
type TBlockThread = Class(TServerClientThread) private FWebClient: TClientSocket; //对web进行数据请求 FWebClientRead: Boolean; //是否可以对web进行数据请求 FRequestInfo: string; FReceiveInfo: TReceiveInfo; //接收的数据流信息 FRecBytesFromWebSend: Integer; //已接收到的Web数据字节数 FWebSendBytes: Integer; //Web服务器需要发送的总字节数 Receive_buf: array[0..8191] of char; //接收缓冲区 Request_buf: array[0..8191] of char; //发送缓冲区,用来保存客户端的请求数据 Request_buf_bytes: integer; //发送缓冲区已经接收的字节数 FReceiveInfoSaved : boolean ; //接收的数据头信息保存标志
procedure InitThread; function SetWebClientInfo(FRequestURLInfo: String): boolean; protected procedure ClientExecute; override; procedure DoTerminate; override; public constructor Create(CreateSuspended: Boolean; ASocket: TServerClientWinSocket); destructor Destroy; override; end;
implementation
//TProxyClientThread constructor TBlockThread.Create(CreateSuspended: Boolean; ASocket: TServerClientWinSocket); begin FWebClient := TClientSocket.Create(nil); FWebClient.ClientType := ctBlocking;
inherited Create(CreateSuspended,ASocket); InitThread; end;
destructor TBlockThread.Destroy; begin FWebClient.Free; inherited Destroy; end;
procedure TBlockThread.InitThread; begin FRecBytesFromWebSend := 0; FWebSendBytes := 0; Request_buf_bytes := 0; FReceiveInfoSaved := false; FWebClientRead := false; end;
function TBlockThread.SetWebClientInfo(FRequestURLInfo: String): boolean; var URL_info: TURLHostInfo; FWebFilter: boolean; begin URL_info := GetURLHostPort(FRequestURLInfo); Result := ( URL_info.HostName <> '' ) and ( URL_info.HostPort > 0 ); FWebClient.Port := URL_info.HostPort; FWebClient.Host := URL_info.HostName; end;
procedure TBlockThread.DoTerminate; begin FRecBytesFromWebSend := 0; FWebSendBytes := 0; FRequestInfo := ''; FReceiveInfoSaved := false; FWebClientRead := false; inherited DoTerminate; end;
procedure TBlockThread.ClientExecute; var ReceiveStream, RequestStream: TWinSocketStream; Rec_Bytes: integer; begin //获取和处理命令直到连接或线程结束 while (not Terminated) and (ClientSocket.Connected) do try //try 1 //创建TWinSocketStream对被代理端进行读写操作 RequestStream := TWinSocketStream.Create(ClientSocket, 60000); try //try 2 //获取被代理端请求 Request_buf_bytes := RequestStream.Read(Request_buf,8192); //如果有请求,设置Web端信息 if Request_buf_bytes > 0 then FWebClientRead := SetWebClientInfo(Request_buf); //Web端通信准备完成,并且访问站点没有被过滤 IfID=1 if FWebClientRead then begin //IFID=1 begin Then method try //try 3 //Web端开始通信 ReceiveStream := TWinSocketStream.Create(FWebClient.Socket, 60000); FWebClient.Active := True; try //try 4 //向Web端发送请求 ReceiveStream.Write(Request_buf,Request_buf_bytes); while (not Terminated) and (FWebClient.Socket.Connected) do begin //接收Web端返回的数据 Rec_bytes := ReceiveStream.Read(Receive_buf,8192);
Inc(FRecBytesFromWebSend,Rec_bytes); //保存Web端返回数据的信息 if not FReceiveInfoSaved then begin FReceiveInfo := AnalyzeReceiveData(Receive_buf); FReceiveInfoSaved := FReceiveInfo.ContentInfo.RequestFound; FWebSendBytes := FReceiveInfo.ContentInfo.ContentSize + FReceiveInfo.RemoteFileInfo.RemoteFileSize; end; //如果被代理端还连接,传送Web端返回的数据 if ClientSocket.Connected then
RequestStream.Write(Receive_buf,Rec_Bytes); if ( FRecBytesFromWebSend >= FWebSendBytes ) or ( Rec_bytes = 0 ) or not ClientSocket.Connected then FWebClient.Close; end; finally //try 4 ReceiveStream.Free; end; finally //try 3 ClientSocket.Close; end; end //IFID=1 end Then method else //IFID=1 begin else method begin//发送拒绝请求信息到客户端 // RequestStream.Write(AccessLimit,sizeof(AccessLimit)); end; finally //try 2 RequestStream.Free; Terminate; end; except //try 1 // HandleException; end; end;
end.
//********************************************************************************** // TServerSocket阻塞线程调用方法 //********************************************************************************** procedure TfrmMain.ServerSocketGetThread(Sender: TObject; ClientSocket: TServerClientWinSocket; var SocketThread: TServerClientThread); begin SocketThread := TBlockThread.Create(false,ClientSocket); end;
|
请发表评论