高手们
请教一下,我的想法是这样的,本地程序通过串口(现在用SPCOMM)跟串口的设备进行实时通讯,而我想不单在这台机子上可以看到数据,其他人也可以通过IE的方式远程访问我这个程序,不知要如何实现呢?菜鸟一个,还请高手们详细指教下,如果有简单的DEMO就最好了,无限感激
请教一下,我的想法是这样的,本地程序通过串口(现在用SPCOMM)跟串口的设备进行实时通讯,而我想不单在这台机子上可以看到数据,其他人也可以通过IE的方式远程访问我这个程序,不知要如何实现呢?菜鸟一个,还请高手们详细指教下,如果有简单的DEMO就最好了,无限感激
解决方案 »
- win2003共享文件夹网络访问
- 怎样动态枚举一个数据库中的所有表?
- 出现216系统错误,如何屏蔽??
- 我将建立库和表以及触发器的SQL语名都存在了一个.SQL文本文件中,我如何在Delphi中一次执行它呀。
- 一个关于COM的问题。
- fastreport找不到EDIT等控件,怎么办??
- 钩子能给我解释一下吗?
- 不停吼……散分消气(二)
- 在EXCEL中实现边框为波浪线,望有识之士详细解答,可留QQ沟通
- 我想得到mp3文件里面的信息,比如歌曲的作者,名称等,有没有什么控件推荐?谢谢!
- cxScheduler 有没有人会用啊!老出错,有例子先!
- MYSQL中如何一次查询多个结构相同的表,返回一个结果集?
2、写入数据库。
3、做网页,刷新数据库的数据。
DELPHI7上有没有简单点的方法啊,继续求教
用idhttpserver直接做个HTTP服务器.
这个服务器,在提供下载htm文件及ocx(或cab)文件的同时,还提供返回当前时刻的串口数据.用idhttpserver的时候,你必须搞清楚一个概念.什么叫"页面".
这个页面,并不是一般意义上的htm,asp,aspx,jsp,php为扩展名的文件了.
它实际上是你的HTTP SERVER返回给客户的浏览器的html格式编码后的数据而已.举个例子:procedure TForm1.IdHTTPServer1CommandGet(AThread: TIdPeerThread;
ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
var
strHTML: string;
begin
strHTML :=
'<html> ' +
'<title>Test Page </title> ' +
'<body>just for test.</body> ' +
'</html>'; if SameText(ARequestInfo.Document, '/mainpage') then
AResponseInfo.ContentText := strHTML;
end;procedure TForm1.Form1Create(Sender: TObject);
begin
IdHTTPServer1.Active := True;
end;
form上就一个idhttpserver.
程序运行起来后,打开IE,输入:http://127.0.0.1/mainpage
就看到"just for test."了.这个并不是一般意义上的页面,即:必须要有一个htm之类的文件存在.可以看出,其实是工程里面的一段字符串而已.当然,你也可以用htm格式的文件.比如,你将一个htm格式的文件,比如:index.htm ,放在当前工程执行文件的同级目录下的wwwroot目录.
你可以这样:
var
slResponse: TStringList;
begin
.....
slResponse := TStringList.Create; slResponse.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'wwwroot\index.htm');
AResponseInfo.ContentText := slResponse.Text;
end;可以根据条件,看ARequestInfo.Document的值是什么,就知道浏览器要取什么数据.对应的返回给它就行了以上这些是返回纯脚本,访问文件也可以,比如图片文件,exe文件,其他文件....
httpserver有个ServeFile的public方法.可以用来回传文件.讲到这里,至少这个http server的功能,可以用来实现静态网页了.再来看你的实时数据,怎么取得.你可以自己定义一个命令号,比如名字叫CommData
如何实现:只要在浏览器里面输入:http://127.0.0.1/CommData 就能得到串口数据呢?
其实很简单.一样,在OnCommandGet事件里面判断:
if ARequestInfo.Document = '/CommData' then
begin
//去读串口,或者缓冲区(buffer)
//这里,我说的缓冲区的意思,就是: 在你的程序里面开辟一段内存,只要spcomm收到数据,就将数据放在这个缓冲区.
AResponseInfo.ContentText := 缓冲区的数据; //还可以以二进制度的形式(流)返回数据
AResponseInfo.ContentStream := .....;
end;ok ,到这一步,就可以在IE上,实时得到串口数据了,但是这些数据,可能呈现的方式不太友好,用户看不懂.没关系,接下来,还得做一个事情,做个ocx,其实就是AtiveX里面的Active Form这个Active Form上放一个TIdHttp控件,一个TTimer控件Timer,定时触发TIdHttp去访问http://127.0.0.1/CommData 这样,IdHttp就能定时得到串口的数据了.这个时候,你再用这些数据,用你想用的方式(比如曲线图什么的),去呈现在Active Form上就好了....不知道说这么多,有没有用.这个模式,我曾经在一个视频监控的项目中用过.当时也是要求,能通过IE,实时浏览视频画面.希望对你有用吧.
就用一般的工程里面的TForm,上面放个idhttpserver和spcomm就行.如果你想做成服务,可以选择File-----New-----Other... New选项卡里面的 Service Application.(可以google下:delphi 服务程序)
然后将idhttpserver和spcomm放到那个服务的模块(界面样子很象TDataModule)里面去.
我说的active form,是给客户端的浏览器下载后,使用的activex程序.是和httpserver独立开来的. (google: delphi avtiveform 或 delphi ActiveX)也就是说你必须要有两个工程,一个工程是用来实现httpserver的,另一个工程,就是编写IE用的activex.唉......不知道这种模式,对你来讲,是不是有点难度,估计你以前都没做过这方面的.这个做完后,还涉及到activex相关的打包(做成cab),数字签名什么的......
然后,就是:直接打开IE,输入地址后,得到httpserver回传的串口数据. 把这步做完了,你的http server就差不多了.我不知道你的串口通信协议是什么格式.现只能做个假设:
上位机往下位机发指令: AA 01 01
下位机应答: AA 01 01 1E
(
说明:
请求部分:
AA: 协议头
01: 命令号 01表示:取温度
01: 总线地址 01表示:第一个温度探头的地址
应答部分:
AA: 协议头
01: 命令号 01表示:返回温度值
01: 总线地址 01表示:第一个温度探头的地址
1E: 温度值 1E = 10进制的30 也就是30摄氏度
)我们先把问题想得简单点:现在的需求就是:HTTP SERVER不断的取得01地址的探头温度.IE每刷新一次,都能显示最新的温度.
好,开始coding:三个控件,名字分别是:IdHttpServer1, Spcomm1, Timer1
另外,在Form1的private里面定义一个缓冲区:
private
FReceiveBuf: array[0..3] of Byte;
再写定时向串口发送命令代码:
procedure TForm1.Timer1Timer(Sender: TObject);
var
arrSendBuf[0..2] of Byte;
begin
//组装发送命令
arrSendBuf[0] := $AA;
arrSendBuf[1] := $01;
arrSendBuf[2] := $01;
//发送命令
SpComm1.WriteData(@arrSendBuf[0], SizeOf(arrSendBuf)); //我机上没装spcomm,不知道是不是这样写.反正就是这个意思.
end;
接收串口数据:
//不知道是不是叫OnReceiveData事件,参数也可能不是这样,反正写在spcomm对应的接收数据的事件里面.
procedure TForm1.Spcomm1ReceiveData(pBuffer: PByte; iCount: Integer);
begin
//保存数据到缓冲区
CopyMemory(@FReceiveBuf[0], pBuffer, iCount);
end;
再来处理HTTP请求:
procedure TForm1.IdHTTPServer1CommandGet(AThread: TIdPeerThread;
ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo); function ByteArrayToString(pBuffer: PByte; iCount: Integer): string;
var
I: Integer;
begin
Result := '';
for I := 0 to iCount - 1 do
begin
Result := Result + IntToHex(pBuffer^, 2);
Inc(pBuffer);
end;
end;begin
if SameText(AResquestInfo.Document, '/CommData') then
begin
AResponseInfo.ContentText := ByteArrayToString(@FReceiveBuf[0], SizeOf(FReceiveBuf)); //将数据转换成能看得懂的16进制的文本形式
end;
end;ok,现在在浏览器里面输入:http://127.0.0.1/commdata 应该能看到串口数据了. 每刷一次,就去取一次最新的数据.到这里,http server就差不多了.
剩下的,就是IE上,怎么呈现这些数据了.
你先去找找有关activeform的资料.上班了......要做事了,有时间再说.
activeform?和c/s又有什么本质的区别,我感觉比c/s的还要复杂一些,而且不能实时的显示,要刷新ie不如用spcomm加上idtcpserver,idtcpclieng
无法用言语表达的感激O(∩_∩)O
对方要求IE能访问,tcpserver里面没有加入HTTP协议的部分.
我能想到的,只有activex.在activex里面,去取数据.activex,最容易的方式,就是activeform.
当然了,在activeform里面,也可以用tcpclient去连tcpserver去取数据.这样一来,对方既得弄个httpserver,又得弄个tcpserver.
IE刷新一次,内部过程就是:IE浏览器向HTTPSERVER提出数据请求(Request),然后,HttpServer根据请求的内容,组织好数据(在本例中,就是在OnCommandGet里面组织数据),回传给IE,IE再去解析HTML格式的数据,以正确的格式显示出来.再举个例子,讲得更细化一点:
按照上面我在7楼回复的内容里面,index.htm的例子来扩展说明.
假设我们wwwroot目录下的index.htm源码如下:
<html>
<body>
<image src="a.gif">
</body>
</html>如果熟悉html语言的话,很容易就看出,这个页面上,就显示一张图片.
打开delphi,将我们的httpserver程序按F9运行(不是直接运行编译好的程序),在oncommandget事件入口处设置断点,
打开浏览器,输入:http://127.0.0.1/index.htm回车.
这个时候,delphi的IDE就停到断点那里.可以查看到ARequestInfo.Document的内容,是: "/index.htm"
然后F9让程序继续走,通过stringlist,读取index.htm的内容,传回去.请注意,这是一次完整的通讯过程,到这里,这次通讯过程就结束了.但是,考虑一下:我们传回去的只是index.htm的内容,里面只是纯文本而已.
并没有将图片传回去. 疑惑马上就得到解答,你会发现这个时候,delphi的IDE,又停在断点那里了,请求又来了.
没错,这次请求的就是图片.你可以看看这次ARequestInfo.Document的内容又是什么.这是因为IE在收到index.htm的内容后,它自己进行解析html源码,
然后判断出,这个图片的地址,也是这个服务器上的,所以它自己会主动过来请求这个图片.
假设,index.htm里面的那个img标签内容,换成<image src="http://www.google.cn/a.gif">那IE就会找google去要文件了.你可以根据这次ARequestInfo.Document的内容,在OnCommandGet事件里面去处理,
这次要传文件了,首先必须判断请求的文件是否存在,废话,不存在我拿什么返回给浏览器?
在文件存在的前提下,如何返回? 就要用到我之前提过的那个IdHttpServer的ServeFile方法了.具体的参数,自己去看吧.
请求图片的第二次通讯,也结束了. 如果index.htm文件里面,除了这个图片外,还包含别的东西,让IE判断出,必须到我们的httpserve上来要,
第三次通讯又来了....罗嗦了这么多,就是为了让楼主在接下来的工作里面,知道怎么将要做的ocx文件(应该是打包后的cab文件),传给浏览器.说说我们这个问题的思路:
之前我们做好的工作,提供http://127.0.0.1/commdata这样的地址,并不是给IE访问的.结果楼主都看到了,需要刷新,才能得到数据.
通讯一次,请求完之后,肯定不会自动再请求了.抽根烟,呵呵,马上继续写...
IE得到index.htm的内容,并解析,再将它要的东西,通过多次请求的方式,显示在IE窗口上后,就完成了.
不会再跟httpserver有任何数据交互了.通过activex技术,就有办法了.activex是基于com技术的. 反正都打了这么多字了,鉴于楼主的能力(不好意思,每个人都有自己专长的方面,我就假设楼主在这方面不太熟了),简单讲下com.
com的东西很复杂,只是非常非常粗略的提一下.
IE里面,通过html代码(<object>标签),嵌入com组件,里面最关键的是一串GUID.IE会根据这个guid,去搜索注册表,
找到对应的键后,在其子键里面,有个地方,记录这个guid对应的执行程序的路径,可能是exe,可能是dll,可能是ocx....
然后IE就会调用这个执行程序提供的相应的接口.回到我们的问题,现在接下来,我们要做的东西,就是上面一段话提到的执行程序.
我们做好这个执行程序后,将它放到wwwroot下面某个地方,让IE在访问index.htm的时候,顺便把这个程序下载到IE浏览器所在的机器上,并注册.
然后IE浏览器,再根据注册表的内容,找到我们这个执行程序,并嵌入到IE页面里面去运行了. 这个执行程序,既然是我们自己做的,那就好办了.
就是之前一直提到的activeform,delphi的很多控件在这个activeform上,都可以使用,比如:TLabel, TEdit, TDbgrid....
我们需要的是: TIdHttp, TTimer.TTimer用来干嘛?IE需要刷新才提交请求吗,我们用Timer在执行程序的内部,来定时向HttpServer提交请求,就不需要总是刷新IE了.
如何向HttpServer请求? 当然是用TIdHttp了. (唉......越来越发现自己喜欢讲废话了.)选择File----New----Other... ActiveX选项卡里面,第一个项目,Active Form,建立activex工程.
编译后,应该是产生一个扩展名为ocx文件吧? (这篇帖子,我写的东西,很多都不是边在delphi ide环境操作,边写帖子,所以可能有些地方会有些疑问或错误)先写好这个工程:private
slCommData: TStringList;FormCreate里面: slCommData := TStringList.Create;procedure TActiveForm.Timer1Timer(Sender: TObject);
begin
//里面的IP,到时候换成HTTPSERVER的服务器地址,直接在本机测试,可以这样写
slCommData.Add(IdHttp1.Get('http://127.0.0.1/commdata'));
end;顺便提一句:
IdHttp1还有一个重载的Get函数,可以返回流,如果之前写httpserver的代码的时候,我们不是用AResponseInfo.ContentText := ...
而是用: AResponseInfo.ContentStream 返回的话,这里,就直接能用get,得到流了.不需要转换成可以识别的16进制的文本了.这里,就很显然了,从IE调用这个ocx执行程序开始,以后的数据,都会保存到StringList里面了.
温度曲线如何实现? 唉....还得做控件去画图...我就不继续说了,反正数据有了,爱咋咋地.需要另外提的几点是:
1.在delphi建立这个activeform之后,
project下面,有Web Deployment Options... 和Web Deploy两个菜单项可以用,它用来产生测试这个ocx的htm文件.
里面自动会加上嵌入这个ocx的html代码.
2.可以使用run下面的install com+ objects(还是register active server的菜单,不记得是哪个了.)可以直接注册这个ocx.
当然也可以直接在命令行,输入: regsvr32 路径+文件名 /install (好象是install吧)
注册后,才能在IE里面看到界面.其实注册的过程,就是调用里面exports的函数:DllRegisterServer,这个函数会往注册表写GUID,写路径....等等.
3.这个ocx也是可以调试的.选择 run ...parameters... 在host application里面填上网址,直接F9就行.
最后,按照上面提到的第1点里面,自动产生的html文件里面的写法,在wwwroot下面建个htm文件,
或者直接把这个自动产生的htm,复制过去.(可能需要改一下) ,应该就可以通过http://127.0.0.1/htm文件名.htm来看到图象了. 在本机上应该是没问题的(只要这个ocx注册过),如果需要其他机器也要能访问,将ocx文件打包成cab文件吧,打包的办法,网上有介绍.
打包成cab,是为了其他机器上的IE访问的时候,能自动下载,注册.另外,可能因为病毒的原因,现在IE对这样的东西,有好多限制,需要对cab文件制作数字签名,这个是要钱的.
网上有那种免费30天的数字签名,我试过了,可以用.如果你不想这么麻烦,可以提供一个小程序,让用户去下载,这个小程序功能就是: 将ocx下载到浏览器的机器上,并注册.
或者将ocx连同这个小程序一起打包,让用户直接下载下去.
完了......
我的目标是 ----> ^_^
多给suton 点
北京思源计算机培训中心(http://www.ciitc.com)
PS:
我的目标是 ----> ^_^
==========================================================
这个,既然数据已经存在数据库中了,做个网页来读取已经是很简单的事了。不论用什么技术,几行代码就可以搞定的!
现在很多工控上面不用网络还是用串口,稳定!
写的工具在xp系统可以正常通讯,在Win7上不能正确使用。
情况是这样的:使用串口通讯,用TidTrivialFTPServer 下载文件,有的文件可以下载成功,有的不可以,下载到中途会不传输了,文件大的会失败,小的文件可以的。
分Block传输的,传一部分的Block后,就不继续传了。
请指点一下,谢谢!