你好,欢迎来到电脑编程技巧与维护杂志社! 杂志社简介广告服务读者反馈编程社区  
合订本订阅
 
 
您的位置:杂志经典 / 编程语言
利用Delphi 封装Mailslots实现网络实时数据广播
 

 : 本文论述了在Win9x,NTWin32操作系统下,利用Delphi 封装MailSlots在局域网内实现实时通讯及网络数据广播。

关键词Mailslots , Win32, 多线程。

 

 MailslotsWindows interprocess communications(IPC)的成员。Slot是通道的意思,顾名思义即Mailslots可在局域网上进行数据通讯。Mailslots的通讯是单方向的,但可很简便的实现网络数据广播。本文主要介绍用Mailslots进行通讯。

一、Maislots的函数

下面看mailslots 的函数

Mailslots Server的主要函数:

CreateMailslot 

建立Server mailslot返回句柄

GetMailslotInfo 返回消息的数目、大小、等待时间等

ReadFile    mailslot内取得消息

CloseHandle 关闭mailslot

Mailslots Client 的主要函数:

CreateFile      建立Client mailslot返回句柄

WriteFile       把数据写入mailslot   

CloseHandle 关闭mailslot

读者也许会感到奇怪,怎么Mailslots和文件I/O函数一样的?mailsots其实是在内存里的临时的虚拟的文件,它和磁盘文件不同的是一旦关闭mailslots,所有在mailslots内的数据会删掉。

二、Mailslots Names

    Mailslots Names 是很重要的,下面介绍它的格式:

CreateMailslot建立Server mailslotmailslot Names必须如下的格式:

    \\.\mailslot\[path]name

  CreateFile 建立Client mailslot , Mailslots Names有几种格式:

1         \\computername\mailslot\[path]name 

消息写入指定的计算机的mailslot, 即消息只有指定的计算机有相同的Mailslot Name才可以接收。

2         \\domainname\mailslot\[path]name

domainname(工作组),工作组内有相同的Mailslot Name都可以接收消息

3         \\*\mailslot\[path]name  

有相同的Mailslot Name(在系统主工作组内)都可以接收消息

如何实现网络广播了,局域网内听众建立相同的Mailslots Names电台23格式便可进行广播。

三、封装好的Tmailslot的源程序

Mailslot.pas 的内容:

//作者:江天送 Jun. 17th 2000

unit MailSlot; interface

uses 

 Windows, SysUtils, Classes;

type TOnReceiveData = procedure(Data: Pointer; Size: Cardinal) of object;

 

type

  TMailSlotThread = class(TThread)  //等待消息的线程

  private

FHandle:THandle;  

//Server Mailslot的句柄

    cbMessage:Cardinal;

  protected

    procedure Execute; override;

    Procedure ReceiveMessage;

  public

     Constructor Create(MSHandle:THandle);

  end;

 

type

  TMailSlot = class(TComponent)

  private

    msthread:TMailSlotThread;

    FActive:Boolean;

    FOnReceiveData:TOnReceiveData;

    procedure SetActive(Value: Boolean);

  protected

  public

    hMailSlot:THandle;

    function WriteData(SlotName:pchar;Data:Pointer;

     DataSize:Cardinal):Boolean;

    function CreateSlot(SlotName:Pchar):Boolean;

    function FreeSlot:Boolean;

  published

    property Active: Boolean read FActive write SetActive;

    property OnReceiveData: TOnReceiveData

      read FOnReceiveData write FOnReceiveData;

  end;

var GOnReceiveData:TOnReceiveData;

procedure ReadMessage(FHandle:THandle;Size:Cardinal);

procedure Register;

implementation

 

procedure Register;

begin

  RegisterComponents('Simple', [TMailSlot]);

end; //注册控件

 

function TMailSlot.CreateSlot(SlotName:Pchar):

  Boolean;

begin //建立Server MailSlot

 hMailSlot:=CreateMailslot(

   SlotName,      //MailSlot Name

   0,            // 没有最大消息长度的限制

   MAILSLOT_WAIT_FOREVER, // 读取消息没有超时限制

        nil);

  if hMailSlot <> INVALID_HANDLE_VALUE then

   begin  //mailslot建立成功,启动线程

     msthread:=TMailSlotThread.Create(hMailSlot);

     GOnReceiveData:=FOnReceiveData;

     Result:=TRUE;

   end;

end;

 

function TMailSlot.FreeSlot:Boolean;

begin

  if hMailSlot=0 then exit;

  msthread.Terminate ;

  CloseHandle(hMailSlot); //关闭Server MailSlot

end;

 

procedure TMailSlot.SetActive(Value:Boolean);

begin //设置线程的活动状态

 FActive:=Value ;

 if msthread=nil then exit;

 if (Value) and (msthread.Suspended)

    then msthread.Resume else msthread.Suspend;

end;

 

function TMailSlot.WriteData(SlotName:pchar;

   Data:Pointer;DataSize:Cardinal):Boolean;

var

hFile:THANDLE ;

cbWritten:DWORD ;

begin        //MailSlot写数据

  hFile := CreateFile(SlotName,GENERIC_WRITE,

    FILE_SHARE_READ, //此处必须用FILE_SHARE_READ

    nil,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,0);

  if  hFile = INVALID_HANDLE_VALUE then

      begin  //CreateFile失败,返回FALSE

        result:=FALSE;

        exit;

      end;

  result:=WriteFile(hFile,data^,datasize,cbWritten,nil);

  CloseHandle(hFile);

end;

 

Constructor TMailSlotThread.Create(MSHandle:THandle);

begin

 Inherited Create(True);

  FreeOnTerminate := True;

  Priority := tpLowest;

  //Priority设得太高会使GetMailSlotInfo出错

  FHandle := MSHandle;

  Resume;

end;

procedure TMailSlotThread.Execute;

var

Nmessage: cardinal;

begin

  freeonterminate:=true;

  repeat

    cbMessage:=0;

    Nmessage:=0;

    GetMailslotInfo( FHandle, //MailSlot的句柄

                     nil,  //没有最大消息长度的限制

                     cbMessage, //下个消息的长度

                     @Nmessage, //消息的个数

                     nil    //读取消息没有超时限制

                     );

   if NMessage>0 then

      Synchronize(receiveMessage);

   until terminated;

end;

procedure ReadMessage(FHandle:THandle;Size:Cardinal);

var cbread:Cardinal;

lpszBuffer:Pointer;

begin

    getmem(lpszbuffer,Size);

    ReadFile(FHandle,lpszBuffer^,

       Size,cbRead, nil);  //读取数据

    if Assigned(GOnReceiveData)

      then GOnReceiveData(lpszbuffer,cbRead);

    freemem(lpszbuffer,Size);

end;

procedure TMailSlotThread.ReceiveMessage;

begin

    ReadMessage(FHandle,cbMessage);

end;

end.

四、TMailSlot控件的使用

    控件的使用很简单,ServerCreateSlot便可建立Server Mailslts,可用Active属性控制是否接收消息,用完别忘了FreeSlot关闭MailSlot

    ClientWriteData便可,用于网络广播每次写数据不可大于424字节。

 

  推荐精品文章

·2024年9月目录 
·2024年8月目录 
·2024年7月目录 
·2024年6月目录 
·2024年5月目录 
·2024年4月目录 
·2024年3月目录 
·2024年2月目录 
·2024年1月目录
·2023年12月目录
·2023年11月目录
·2023年10月目录
·2023年9月目录 
·2023年8月目录 

  联系方式
TEL:010-82561037
Fax: 010-82561614
QQ: 100164630
Mail:gaojian@comprg.com.cn

  友情链接
 
Copyright 2001-2010, www.comprg.com.cn, All Rights Reserved
京ICP备14022230号-1,电话/传真:010-82561037 82561614 ,Mail:gaojian@comprg.com.cn
地址:北京市海淀区远大路20号宝蓝大厦E座704,邮编:100089