- 浏览: 2058779 次
- 性别:
- 来自: 厦门
文章分类
- 全部博客 (1409)
- asp/asp.net学习 (241)
- oracle (10)
- delphi (295)
- java (27)
- pb (1)
- 每日点滴 (49)
- 学习方法 (40)
- 思想方面 (104)
- C语言 (5)
- C++ (1)
- 代码重构经验 (5)
- 软件工程 (3)
- 数据库 (99)
- 英语学习 (3)
- mysql (1)
- 该关注的网站或者网页 (42)
- 总结 (7)
- 要去做的事情 (33)
- 算法 (1)
- 网络方面 (29)
- 随感 (96)
- 操作系统 (36)
- UML (12)
- 常用工具的使用 (55)
- 脚本 (7)
- 汇编 (62)
- 数据结构 (2)
- 财务 (38)
- 语文作文 (16)
- 法律 (1)
- 股票 (88)
最新评论
-
devwang_com:
可以,学习了~~
列出文件夹下所有文件夹的树形结构--Dos命令 tree的使用 -
hvang1988:
不管用啊 frxrprt1.PreviewForm.Pare ...
fastReport预览时嵌入到别的窗体 -
00915132:
我也有这个疑问,非常 感 谢
left join加上where条件的困惑 --SQL优化 -
zhuyoulong:
学习了,高效读书
软件架构师要读的书 -
nTalgar:
非常感谢分享!
Application.ProcessMessages用法:
转自:http://www.knowsky.com/335289.html
读一读Scktsrvr.exe的源程序
使用DELPHI做多层开发的朋友们都应该对Scktsrvr.exe这个程序不陌生的,
Borland公司在DELPHI中给出了它的源代码。
这是一个900来行的程序,程序不算长,
现在我只选其中部分仔细读一读。
走的线路大致是,从服务器接到客户端连接,处理客户端的一个请求(这儿
选了客户端向服务器发出的'取应用服务器列表'请求)
服务器接受了客户端连接后,
因为ServerSocket采用的是阻塞模式,服务器执行了下面这个线程来
服务客户端:
//SCKTMAIN.PAS
procedure TSocketDispatcherThread.ClientExecute;
var
Data: IDataBlock;
msg: TMsg;
Obj: ISendDataBlock;
Event: THandle;
WaitTime: DWord;
begin
CoInitialize(nil); //初始化COM
try
Synchronize(AddClient); //在程序界面上显示客户信息,
//用同步保证AddClient线程安全性
FTransport := CreateServerTransport;
try
Event := FTransport.GetWaitEvent;
PeekMessage(msg, 0, WM_USER, WM_USER, PM_NOREMOVE);
GetInterface(ISendDataBlock, Obj);
if FRegisteredOnly then
FInterpreter := TDataBlockInterpreter.Create(Obj, SSockets) else
FInterpreter := TDataBlockInterpreter.Create(Obj, ');
try
Obj := nil;
if FTimeout = 0 then
WaitTime := INFINITE else
WaitTime := 60000;
while not Terminated and FTransport.Connected do
try
case MsgWaitForMultipleObjects(1, Event, False, WaitTime, QS_ALLEVENTS) of
//MsgWaitForMultipleObjects保持线程同步之用,
//本文暂不细说它.
WAIT_OBJECT_0: //有数据来了
begin
WSAResetEvent(Event);
Data := FTransport.Receive(False, 0); //从客户端接收数据块
if Assigned(Data) then
begin
FLastActivity := Now;
FInterpreter.InterpretData(Data);//下面接着分析这儿
Data := nil;
FLastActivity := Now;
end;
end;
WAIT_OBJECT_0 + 1:
while PeekMessage(msg, 0, 0, 0, PM_REMOVE) do
DispatchMessage(msg);
WAIT_TIMEOUT:
if (FTimeout > 0) and ((Now - FLastActivity) > FTimeout) then
FTransport.Connected := False;
end;
except
FTransport.Connected := False;
end;
finally
FInterpreter.Free;
FInterpreter := nil;
end;
finally
FTransport := nil;
end;
finally
CoUninitialize;
Synchronize(RemoveClient);
end;
end;
就这么舒舒服服的六十来行。
除开那些流程控制的语句,我们主要看到两个东西:
数据传输(FTransport) 和 数据解析(FInterpreter)。
在本文中,我更感兴趣的是它的应用协议的实现,
数据传输(FTransport)就先扔在一边,以后再看了.
现在我们就来看看它的数据解析部分。
。。。
FInterpreter := TDataBlockInterpreter.Create(Obj, SSockets) else
FInterpreter := TDataBlockInterpreter.Create(Obj, ');
//这两种创建TDataBlockInterpreter类实例的方法的区别也不去管它.
。。。
FInterpreter.InterpretData(Data);
。。。
就是这儿,就是这么一句。
它具体到底干了些什么呢??
================
。。。
type
TSocketDispatcherThread = class(TServerClientThread, ISendDataBlock)
private
。。。
FInterpreter: TDataBlockInterpreter;
FTransport: ITransport;
。。。
================
FInterpreter这个对象引用就是这儿定义的。
procedure TDataBlockInterpreter.InterpretData(const Data: IDataBlock);
var
Action: Integer;
begin
Action := Data.Signature;//取出由客户端传来的数据块中请求标志值
//客户端数据块的具体数据格式等会儿说.
if (Action and asMask) = asError then DoException(Data);
try
case (Action and asMask) of //根据客户端的请求标志值作相应的处理.
//呵,就只有这么几个。一个大型的MIDAS系统
//就全站在它们肩上.
asInvoke: DoInvoke(Data);
asGetID: DoGetIDsOfNames(Data);
asCreateObject: DoCreateObject(Data);
asFreeObject: DoFreeObject(Data);
asGetServers: DoGetServerList(Data);
asGetAppServers: DoGetAppServerList(Data);//取这个再进一步读一读.
else
if not DoCustomAction(Action and asMask, Data) then
raise EInterpreterError.CreateResFmt(@SInvalidAction, [Action and asMask]);
end;
except
on E: Exception do
begin
Data.Clear;
WriteVariant(E.Message, Data);
Data.Signature := ResultSig or asError;
FSendDataBlock.Send(Data, False);
end;
end;
end;
==========================
顺着线一步步摸下去,
看它是怎么取APPSERVER列表返回客户端的。
很简单,就是通过GetMIDASAppServerList取本地的MIDAS应用服务
器列表,然后将其写在Data中,传回客户端就了事。
===========================
procedure TDataBlockInterpreter.DoGetAppServerList(const Data: IDataBlock);
var
VList: OleVariant;
List: TStringList;
i: Integer;
begin
Data.Clear;
List := TStringList.Create;
try
GetMIDASAppServerList(List, FCheckRegValue);//取本机的应用服务器列表
//想知道它是怎么做的吗?
//源码上都有,自己看.
if List.Count > 0 then
begin
VList := VarArrayCreate([0, List.Count - 1], varOleStr);
for i := 0 to List.Count - 1 do
VList[i] := List[i];
end else
VList := NULL;
finally
List.Free;
end;
WriteVariant(VList, Data);
Data.Signature := ResultSig or asGetAppServers;
FSendDataBlock.Send(Data, False);//将应用服务器列表传回客户端
end;
========================================================
哦..前面还有一个地方没有说,就是这个神秘的Data的数据格式,它是以接口
形式提供的,
这个程序中用的是TDataBlock中实现的这个接口.
源码中可以看出,TDataBlock中包含了一个Stream,
function TDataBlock.GetSize: Integer;
begin
Result := FStream.Size - BytesReserved;//BytesReserved的值这儿是8
end;
从这儿可以看出.数据块是从Stream的第8个字节算起,前面就是两个int型数的位置了.
function TDataBlock.GetSignature: Integer;
begin
FStream.Position := 0;
FStream.Read(Result, SizeOf(Result));
end;
呵, 没错, Stream的头四字节就是它的Signature.客户端的请求标志就是放在这儿.
function TDataBlock.GetStream: TStream;
var
DataSize: Integer;
begin
FStream.Position := 4;
DataSize := FStream.Size - BytesReserved;
FStream.Write(DataSize, SizeOf(DataSize));
FStream.Position := 0;
Result := FStream;
end;
这儿很明显,就是Data中包含数据的长度值.
需要提一下的是,如果你想改变一下传输数据块的格式,比如给它加密加压什么的,
中需要自己来实现IDataBlock接口,替掉TDataBlock就是了.
从这些源码中可以得到很多东西,无论是从优美的风格上,
无论是通讯程序开发还是MIDAS数据库以及DCOM学习或应用者,
它都是值得一读的源程序.
我觉得,更重要的是,它提供了一个严谨优美和实际的范例,更给出了
一个灵活实用的框架体系。
资料引用:http://www.knowsky.com/335289.html
发表评论
-
form打开时的关闭代码
2011-10-25 20:29 1574摘自:http://topic.csdn.n ... -
TUpdateSQL更新问题 提示Update Failed
2011-08-29 20:26 1238摘自:http://topic.csdn.net/u/200 ... -
图解如何用Eurekalog跟踪程序错误
2011-08-12 07:28 941图解如何用Eurekalog跟踪程序错误 摘自:h ... -
VirtualBox 复制VDI 并能创建新的虚拟机
2011-07-21 11:14 2739摘自:http://www.nonabyte.net/how- ... -
截获所有异常 不报错
2011-07-12 16:52 1239摘自:http://media.ccidnet.c ... -
delphi exe程序以及DLL程序如何在模块内部获得各自的路径
2011-07-11 16:38 1305delphi Exe程序以及DLL程序如何在模块内部获得各自的 ... -
Delphi文本文件读写
2011-07-11 14:55 1244Delphi文本文件读写 (2008-10-31 1 ... -
Delphi自定义的消息的使用
2011-05-31 14:12 2315阅:已验证,可通过; 摘自:http://blog.1 ... -
怎么查看OutputDebugString输出的信息?debugview
2011-05-25 16:02 3835网上很多说用debugview查看,我自己写了一个程序,里面用 ... -
Delphi里查看该变量的内存值
2011-05-25 13:32 1122Delphi里查看该变量的内存值:Run==>Evalu ... -
注册表操作 写入autorun启动项,键值为本程序的全路径
2011-05-20 15:40 1825procedure TForm4.Button2Click ... -
报说包frx7和frxdb7都包含了某个单元的错误
2011-05-11 09:59 10221. 问题描述:在安装FastReport3的时候,安装到- ... -
Delphi中使用ListView和TreeView的Item中的Data可能被忽略的内存泄漏
2011-05-03 14:34 1462摘自:http://blog.csdn.net/g ... -
WM_USER的说明 用户消息ID
2011-04-28 10:46 1687WM_USER 摘自:http://baike.bai ... -
ToolButton不能改变大小
2011-04-28 10:38 3462问题描述:ToolButton不能改变大小? 问 ... -
Delphi里TOOLBAR 上的button的caption为什么显示不出来啊
2011-04-20 17:55 1767Delphi里TOOLBAR 上的button的caption ... -
delphi指针简单入门
2011-04-11 21:42 1156摘自:http://topic.csdn.net/t/2003 ... -
Delphi中paramstr的用法 应用程序间传递数据
2011-04-01 14:33 2104Delphi中paramstr的用法 应用程序间传递数据 ... -
Delphi中的THashedStringList对象 --大数据量时
2011-04-01 13:54 5148Delphi中的THashedStringLi ... -
inherited Create(AOwner); 和直接写inherited有区别吗
2011-03-26 15:44 1324摘自:http://zhidao.baidu.com/que ...
相关推荐
scktsrvr.exe
这是因为 `scktsrvr` 服务通常作为 COM+ 应用程序的一部分运行。如果端口被更改,而 COM+ 配置没有相应更新,则可能导致服务无法正确启动或运行。 为了确保 `scktsrvr` 和 COM+ 之间的兼容性,需要注意以下几点: ...
- **scktsrvr.exe**:这是编译后的可执行文件,包含了编译后的所有代码和资源,可以直接运行在支持的平台上,作为服务器端程序为客户端提供服务。 - **ScktMain.pas**:这是Delphi的源代码文件,包含了Delphi ...
ScktSrvr改造版。在客户端请求超时时,关闭COM+方法一下。防止多客户端出现假死现象。在关闭COM+方法后,所有的排队中的客户端请求会失败。客户端应设计为在当前请求失败时,可以手工再次请求。再次请求COM+方法,...
包含D6和D7版的全部原码,在Midas数据库编程中,如果客户端采用Socket连接,服务端要运行Borland Socket Server程序,老版本程序在服务器(一个CPU以上)上运行有问题,客户端程序容易出现停止响应的现象。...
Borland Socket Server(ScktSrvr.exe)是Borland公司提供的一个Socket服务器程序,主要用于支持基于Borland的MIDAS框架进行多层应用开发。它不仅是一个强大的工具,也是一个学习Socket编程的好例子。ScktSrvr.exe的...
本程序运用access数据库,如要用sqlserver2000,需还原back下的数据库,数据库名为“图书馆管理系统“,并在服务器端重建连接:1、先运行接口程序scktsrvr.exe,用本程序提供广域网的连接2、运行server.exe3、最后运行...
1先运行接口程序scktsrvr.exe,用本程序提供广域网的连接 2运行server.exe 3最后运行客户端和管理的应用程序 为了数据不被册除,本程序只提供在数据集的post方法,不提供Tclientdataset的appliupdate,若要...
行scktsrvr.exe (在Delphi目?) (3).?行swMMC.exe ,看看「服??」是否已???了所有的「??(DLL)」 (4).?行Demo1.exe 注意事?: (1).必?先修改所有的INI文件,以?合你的?? (2).必?先?行swServer2.exe,才可以...
本程序运用access数据库,如要用sqlserver2000,需还原back下的数据库,数据库名为“图书馆管理 ...1先运行接口程序scktsrvr.exe,用本程序提供广域网的连接 2运行server.exe 3最后运行客户端和管理的应用程序
此版只具备单机功能,单机使用和安装版没有...scktsrvr.exe为数据套接。 GraspSvr.exe管家婆服务器(为零位PJ) GraspStd4.exe为执行程序 启动顺序:数据服务器-数据套接-管家婆服务器-执行程序 退出顺序:则反之
1、使用Socket方式和应用程序服务器相连,Socket使用TCP/IP协议来和应用程序服务器相连,只要客户端计算机支持TCP/IP的连接方式即可,不过对于应用程序服务器来说,必须额外运行Scktsrvr.exe(该程序在Delphi安装...
运行scktsrvr.exe 6.在桌面上运行客户端软件。 7.用户名与口令在表:operator内找。 ................................... E-Mail:cuishouj@263.net 单用户免费使用,下载:...
* 运行管家婆数据套接字 scktsrvr.exe * 运行管家婆服务器 GraspSvr.ExE 4. 数据库连接参数设置: * 填入服务器名称 * 设置数据库连接参数 5. SQL Server 2000 运行环境: * 操作系统:Windows XP 32 位、...
在服务器端,打开`scktsrvr.exe`,这是一个服务器端的应用,用于处理客户端的连接请求。你需要在服务器端设置`GUID`,这个`GUID`与`Intrcpt.dll`的`GUID`相同,确保服务器知道如何处理压缩的数据。同时,服务器端的`...
`ScktSrvr.exe` 是编译后的可执行文件,它是Socket Server的主程序,负责运行服务器并处理客户端的连接请求。在部署Socket服务器时,`ScktSrvr.exe`是实际在服务器上运行的部分。 `ScktMain.pas` 是一个Pascal源...
366++是该系列的一个版本,其中scktsrvr是系统中的一个重要组件,主要负责网络通信和服务端的处理。本篇将详细讲解如何对scktsrvr的菜单进行汉化,以便于用户更好地理解和操作。 1. **scktsrvr组件解析**: ...
"server.exe"和"scktsrvr.exe"可能是系统的服务端程序,负责处理客户端的请求,进行数据处理和交互。它们可能通过TCP/IP协议实现客户端服务器通信,确保系统的网络功能。 "server.cfg"可能是服务器的配置文件,记录...
2. 运行管家婆数据套接字 scktsrvr.exe。 3. 运行管家婆服务器 GraspSvr.ExE。 4. 在桌面右下角出现管家婆图标。 配置数据库连接参数 1. 右键点击桌面右下角的管家婆图标,选择:“设置数据库连接参数”。 2. 在弹...
内容索引:Delphi源码,数据库应用,论文,三层 三层架构Delphi图书查询系统(论文+文档),数据库支持:...本系统应先运行接口程序scktsrvr.exe广域网连接服务,然后运行server.exe,最后启动客户端和管理的应用程序。