delphi TServerSocket阻塞线程单元 实例
TServerSocket阻塞线程单元,希望对你有所帮助。需要注意的是:
1、如果你使用TServerSocket的stNonBlocking模式,重写TServerClientThread线程时要重载
TServerClientThread的ClientExecute过程,写你自己的处理过程;
2、如果在线程内部调用外部的过程,建议使用同步化方法;
3、线程访问线程内部变量的速度远远高于线程访问线程内部变量的速度
如果有问题的话,可以和我联系 Email: rurality@21cn.com
//**********************************************************************************
//说明: TServerSocket阻塞线程
//作者: licwing 时间: 2001-4-21
//Email: rurality@21cn.com
//**********************************************************************************
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;
delphi TServerSocket阻塞线程单元 实例的更多相关文章
- Delphi Socket 阻塞线程下为什么不触发OnRead和OnWrite事件
//**********************************************************************************//说明: 阻塞线程下为什么不触 ...
- Delphi中的线程类 - TThread详解
Delphi中的线程类 - TThread详解 2011年06月27日 星期一 20:28 Delphi中有一个线程类TThread是用来实现多线程编程的,这个绝大多数Delphi书藉都有说到,但基本 ...
- Delphi中的线程类(转)
Delphi中的线程类 (转) Delphi中有一个线程类TThread是用来实现多线程编程的,这个绝大多数Delphi书藉都有说到,但基本上都是对 TThread类的几个成员作一简单介绍,再说明一下 ...
- 主窗体里面打开子窗体&&打印饼图《Delphi 6数据库开发典型实例》--图表的绘制
\Delphi 6数据库开发典型实例\图表的绘制 1.在主窗体里面打开子窗体:ShowForm(Tfrm_Print); procedure Tfrm_Main.ShowForm(AFormClass ...
- Delphi ActiveX Form的使用实例
Delphi ActiveX Form的使用实例 By knityster 1. ActiveX控件简介 ActiveX控件也就是一般所说的OCX控件,它是ActiveX技术的一部分. ActiveX ...
- tornado 异步调用系统命令和非阻塞线程池
项目中异步调用 ping 和 nmap 实现对目标 ip 和所在网关的探测 Subprocess.STREAM 不用担心进程返回数据过大造成的死锁, Subprocess.PIPE 会有这个问题. i ...
- 使用runloop阻塞线程的正确写法
使用runloop阻塞线程的正确写法 runloop可以阻塞线程,等待其他线程执行后再执行. 比如: @implementation ViewController{ BOOL end;}…– ( ...
- Delphi调用SQL分页存储过程实例
Delphi调用SQL分页存储过程实例 (-- ::)转载▼ 标签: it 分类: Delphi相关 //-----下面是一个支持任意表的 SQL SERVER2000分页存储过程 //----分页存 ...
- java线程池实例
目的 了解线程池的知识后,写个线程池实例,熟悉多线程开发,建议看jdk线程池源码,跟大师比,才知道差距啊O(∩_∩)O 线程池类 package thread.pool2; impor ...
随机推荐
- html初学(一)
学习了一些html的基本用法,代码和效果如下: <!DOCTYPE html> <html> <head> <meta charset="utf-8 ...
- TKinter的常用组件
python提供了多个图形开发界面的库,几个常用Python GUI库如下: Tkinter: Tkinter模块("Tk 接口")是Python的标准Tk GUI工具包的接口.T ...
- CentOS 系统配置完jdk,tomcat mysql,nginx 项目发布步骤
1.启动项目之前,一定要先启动nginx服务 重启nginx服务的命令:./nginx -s reload 2.然后启动三个tomcat的服务 3.如果只能进入tomcat,不能进入项目:把tomca ...
- ason 和 Java 对象转化示例
1.工程 2.代码: JsonUtil.java package com.my.json; import java.util.ArrayList; import java.util.List; imp ...
- 【python】浅谈enumerate 函数
enumerate 函数用于遍历序列中的元素以及它们的坐标: >>> for i,j in enumerate(('a','b','c')): print i,j 0 a 1 b ...
- sphinx 配置sphinx.conf
sphinx的配置文件是在配置的时候最容易出错的了: 基本概念: source:数据源,数据是从什么地方来的. index:索引,当有数据源之后,从数据源处构建索引.索引实际上就是相当于一个字典检索. ...
- C#读取系统信息
using System; using System.Management; namespace Soyee.Comm { /// <summary> /// Computer Infor ...
- Winfrom DateGridView 实现Button列禁用
Form窗体如下所示: 实现如下: using System; using System.Collections.Generic; using System.Drawing; using System ...
- C#中判断子窗体是否存在
可在父窗体中定义一个全局变量 public static Form form; 然后在秀出子窗体的点击事件中增加加下代码 if (form == null) { //窗体不存在时,实例化子窗体,并显示 ...
- java命令行HPROF Profiler
The HPROF Profiler The Heap and CPU Profiling Agent (HPROF)是JAVA2 SDK自带的一个简单的profiler代理,它通过与Java Vir ...