高手们
   请教一下,我的想法是这样的,本地程序通过串口(现在用SPCOMM)跟串口的设备进行实时通讯,而我想不单在这台机子上可以看到数据,其他人也可以通过IE的方式远程访问我这个程序,不知要如何实现呢?菜鸟一个,还请高手们详细指教下,如果有简单的DEMO就最好了,无限感激

解决方案 »

  1.   

    这个DEMO恐怕没人有吧?这是一个完整的系统,大家只能提解决的建议。1、读串口数据。
    2、写入数据库。
    3、做网页,刷新数据库的数据。
      

  2.   

    谢谢前面两位兄台的回答啊,就是希望能够详细一点啊,比如我用串口采集上来的数据,我是保存在数据库上面的(用ACCESS,或者SQL2000),那要怎样做成网页让别人从IE看到啊,恳请大家详细说明下啦,谢谢
      

  3.   

    做网页最好用其他语言,最简单的asp,现在流行 .net
      

  4.   

    好像是C/S + B/S结构的系统哦!呵呵
      

  5.   

    谢谢你们的回答啊,顺便看了下旁边的帖子,一直不明白是不是一个WEB Server 可以做到啊,概念不是很清楚,如果做网站的话,那么程序就相当于做两遍啦,要改的话也比较麻烦啊,
    DELPHI7上有没有简单点的方法啊,继续求教
      

  6.   

    不知道你采集的数据量大不大,如果1秒钟就好几组数据,时间长了,数据库会很大.如果你不关心历史数据,只想显示实时数据的话,可以这样实现:
    用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,实时浏览视频画面.希望对你有用吧.
      

  7.   

    很感激楼上suton 大哥的回答啊,我自己测试了下可以实现第一个那个静态网页的浏览啦,但是初学还不是很了解关于读取串口数据到ActiveForm如何实现啊,不知Sunton大哥能否提供一个简单的demo给我呢,就按照你的思路在ActiveForm放置一个idhttpserver和time,和一个edit,和一个spcomm(串口),如能提供,万分感激我的邮箱是:[email protected]还有就是我也按照你的思路上网找了资料,但是关于这方面的还是不多啊,不知有哪些好点的书籍和资料有关这方面的介绍呢,真是感激不尽,谢谢
      

  8.   

    http server不要用active form.
    就用一般的工程里面的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),数字签名什么的......
      

  9.   

    你如果有兴趣的话,不妨继续做下去.静态的HTTP SERVER,你实现了.
    然后,就是:直接打开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的资料.上班了......要做事了,有时间再说.
      

  10.   

    太感谢SUTON兄了,我想试试看,
      

  11.   

    DElphi共享WEB的功能称: Isapi和较新的WebSnap,要下点功夫
      

  12.   


    activeform?和c/s又有什么本质的区别,我感觉比c/s的还要复杂一些,而且不能实时的显示,要刷新ie不如用spcomm加上idtcpserver,idtcpclieng
      

  13.   

    哈,按照suton 兄的方法,第二步又可以实现SPCOMM串口数据在网页上显示啦,就是那个网页的数据不是动态更新啊,要手动按网页上的刷新才会刷新啊,还是SUNTON兄厉害,一下子帖子就变推荐了,哈,期待SUNTON兄关于ActiveFormD 的帮助啊,
    无法用言语表达的感激O(∩_∩)O
      

  14.   


    对方要求IE能访问,tcpserver里面没有加入HTTP协议的部分.
      

  15.   

    在IE里面,如果不刷新页面,要显示温度-time 的曲线图,怎么显示?
    我能想到的,只有activex.在activex里面,去取数据.activex,最容易的方式,就是activeform.
    当然了,在activeform里面,也可以用tcpclient去连tcpserver去取数据.这样一来,对方既得弄个httpserver,又得弄个tcpserver.
      

  16.   

    话说回来,个人认为,CS和BS从原理上来讲,其实没什么区别.BS就是CS的一种表现形式,只是客户端程序不用写,浏览器就是客户端程序.
      

  17.   

    感谢 shuihan20e 的参与,如果有好的想法,可以一起讨论.
      

  18.   

    接下来,就是要达到:不需要用户点IE的刷新按钮,能看到从访问网址的时刻开始,温度的实时曲线变化图.先提一提HTTP协议的通讯过程:
    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访问的.结果楼主都看到了,需要刷新,才能得到数据.
    通讯一次,请求完之后,肯定不会自动再请求了.抽根烟,呵呵,马上继续写...
      

  19.   

    <接上次内容>
    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连同这个小程序一起打包,让用户直接下载下去.
    完了......
      

  20.   

    我好笨啊,都看不懂PS: 
    我的目标是 ----> ^_^
      

  21.   

    啥也不说了,贴子加分吧!
    多给suton 点
      

  22.   

    哥们,怎样通过网页来读取数据呢,要调用API,还是安装个ActiveX,因为好像ASP.NET没看到这样的控件哈
      

  23.   

    两个系统啦,DELPHI做的程序只管采集数据,放到数据库中.做一个BS的程序,也用这个数据库,发布数据.定义好表个,两个系统就可以独立实现了.
      

  24.   

    重新看了一遍,是在服务器上安装一个程序获得数据,然后保存到数据库,通过WEB调用数据库中的数据,有点眉头了
      

  25.   

    向高手学习,佩服^^^^^^=================================
    北京思源计算机培训中心(http://www.ciitc.com)
      

  26.   

    我没看懂题目要干什么?不过感觉 web service 好像可以解决你的问题。有兴趣可以查查这方面资料
      

  27.   

    ACE + ocx 不知道可行不,呵呵
      

  28.   

    MARK
    PS: 
    我的目标是 ----> ^_^
      

  29.   

    libserial-0.6.0rc1.tar.gz + wt-2.2.1
      

  30.   

    好咯,结贴啦,非常感谢SUTON兄的详细解释啊,我会按照这个思路再研究下去啦,希望我们这个DELPHI版多点SUTON兄的好人,让我们这个版再兴旺起来啊,也希望认同DELPHI的人会越来越多啊,谢谢
      

  31.   

    谢谢前面两位兄台的回答啊,就是希望能够详细一点啊,比如我用串口采集上来的数据,我是保存在数据库上面的(用ACCESS,或者SQL2000),那要怎样做成网页让别人从IE看到啊,恳请大家详细说明下啦,谢谢
    ==========================================================
    这个,既然数据已经存在数据库中了,做个网页来读取已经是很简单的事了。不论用什么技术,几行代码就可以搞定的!
      

  32.   

    只是简单的通过网页远程查看数据,没必要用web service
      

  33.   

    串口的DEMO很多了
    现在很多工控上面不用网络还是用串口,稳定!
      

  34.   

    装个iis,在里面创建个线程收发串口数据就ok啦。
      

  35.   

    呵呵,综合性应用对delphi的掌握程度以及其他的相关知识要求比较高,但我觉得首先把架构想好,至于用什么技术就仁者见仁,智者见智了...不过个人感觉B/S形式的C/S很多时候并不必通常意义上的C/S来得好用,最大的优势是不用开发客户端!
      

  36.   

    学习了,另外,请教一个问题。
    写的工具在xp系统可以正常通讯,在Win7上不能正确使用。
    情况是这样的:使用串口通讯,用TidTrivialFTPServer 下载文件,有的文件可以下载成功,有的不可以,下载到中途会不传输了,文件大的会失败,小的文件可以的。
    分Block传输的,传一部分的Block后,就不继续传了。
    请指点一下,谢谢!