红外端口编程 (200分)
分类:局域网 / 通讯 goujie (2003-08-30 21:20:00)
我买了一个USB的红外设备,我可以通过WINDOWS的网络连接和我的手机传送数据,但是我怎么用程序通过它来发送和接收数据呢?小弟查了些资料,好像要用winsock,小弟实在没有搞明白,请各位帮帮指点指点,先谢谢了。
爱元元的哥哥 (2003-08-30 21:23:00)
6.2 红外线套接字
红外线套接字称为I r S o c k,它是一个令人兴奋不已的新技术,首先在Wi n d o w s平台上亮相。
红外线套接字允许两台计算机通过红外线串行端口进行通信。目前,红外线套接字可在
Windows 98和Windows 2000上使用。红外线套接字不同于传统意义上针对便携机的短暂性而
设计的套接字。它们展示了一种新的名字解析模型,下一小节中将对此进行讨论。
6.2.1 定址
由于带有“红外线数据联盟”(Infrared Data Association, IrDA)设备的大多数计算机可
能经常性地拆卸,传统的名字解析方案不能满足人们的需求。传统解析方法充当命名服务器
之类的静态资源—人们在移动正在运行网络客户任务的手提式电脑或膝上型计算机时,是
不能使用这些资源的。为解决这一问题, I r D A就设计成了这样:无须在整个大型网络上,只
须用一种特定的方式浏览范围内的资源,因此, I r D A没有使用标准的Wi n s o c k命名服务函数和
I P定址。相反,命名服务已并入通信流,另外还引入了一个新的地址家族,以支持与红外线
串行端口绑定在一起的服务。I r S o c k地址结构中包含一个服务名(它对绑定和连接调用中所使
用的应用进行描述)和一个设备标识符(描述运行服务的设备)。这里的服务名和设备标识符
类似于传统T C P / I P套接字所用的I P地址和端口号字元组。I r S o c k地址结构的定义如下:
i r d a A d d r e s s F a m i l y字段一直都是A F _ I R D A。i r d a D e v i c e I D是一个4字符的字串,用于唯一
性地标识特定服务所运行的设备。在建立I r S o c k服务器时,这个字段是忽略不计的。但是对客
户机而言,却非常重要,因为它指定的是准备连接的那个I r D A设备(也可能有若干个)。最后,
i r d a S e r v i c e N a m e字段是服务名,应用要么利用这项服务对其本身进行注册,要么试着与这项
服务建立连接。
6.2.2 名字解析
定址可以利用“ I r D A逻辑服务访问点选择符( L S A P - S E L)”或“信息访问服务”(I A S)
注册的服务为基础。I A S从一个L S A P - S E L中摘出一项服务,并把它置入用户友好的文本服务
名中,方式和互联网域名服务器把名字映射到数字化I P地址差不多。要成功建立一个连接,
既可以用L S A P - S E L,又可以用用户友好名。不过,用户友好名需要名字解析。大多数时候,
都不要使用直接的L S A P - S E L“地址”,因为I r D A服务的地址空间是限制了的。Wi n 3 2实施方
案允许L S A P - S E L整数标识符,标识符的范围是1到1 2 7。从本质上说,我们可把I A S服务器当
作一个W I N S服务器,因为它把L S A P - S E L和一个文字化的服务名关联在一起。
事实上的I A S条目有三个重要字段:类名、属性和属性值。举个例子来说,一个服务器希
望在服务名M y S e r v e r下对其本身进行注册。这是服务器通过相应的S O C K A D D R _ I R D A结构执
行绑定调用时完成的。这种情况一旦发生,就会增加一个I A S条目,该条目中包括类名
M y S e r v e r、属性I r D A : Ti n y T P : L s a p - S E L和属性值3。属性值就是下一个未用过的L S A P - S E L,
这个L S A P - S E L 是系统根据注册来分配的。另一方面,客户机向连接调用投递一个
S O C K A D D R _ I R D A 结构。随后便开始I A S 查找,查找带有类名M y S e r v e r 和属性
I r D A : Ti n y T P : L s a p - S E L的那项服务。I A S查询会返回3这个值。用户可利用g e t s o c k e t o p t调用中
的套接字选项I R L M P _ I A S _ Q U E RY来定制自己的I A S查询。
如果打算完全忽略I A S(一般不建议使用),则可为客户机准备连接的服务名或终端直接
指定一个L A S P - S E L地址。忽略I A S后,就只能和不提供任何I A S注册的老I r D A设备(比如红
外线打印机)进行通信。把S O C K A D D R _ I R D A结构中的服务名指定为L S A P - S E L - x x x,就可
忽略I A S注册和查找。其中, x x x处是属性值,其范围在1到1 2 7之间。对服务器而言,这样会
直接为该服务器分配特定的L S A P - S E L地址(假定这个L S A P - S E L地址尚未使用)。对客户机
而言,这样会忽略I A S查找,并试图马上与运行于指定的L S A P - S E L上的任何一项服务建立连
接。
6.2.3 红外线设备列举
由于红外线设备的使用地点不固定,因此,必须有一种方法,可以动态地把特定范围内
的所有可用红外线设备列举出来。我们先从Windows CE实施方案和Windows 98及Wi n d o w s
2 0 0 0实施方案之间的几点差别谈起。Windows CE先于其他平台支持I r S o c k,并提供少量与红
外线设备有关的信息。后来, Windows 98和Windows 2000也开始支持I r S o c k,但它们新增了
另外的“提示”信息,该信息是由列举请求返回的(关于提示信息,我们稍后将简要论述)。
108计计第二部分附Winsock API
下载
这样一来,Windows CE的A F _ i r d a . h头文件中包含的是原始的、少量的结构定义;但是,其他
平台提供的新的头文件中包含的则是目前支持I r S o c k的各个平台的条件结构定义。为了保持一
致,我们建议大家采用较新的A f _ i r d a . h头文件。
列举临近红外线设备的方法是采用g e t s o c k o p t的I R L M P _ E N U M _ D E V I C E 命令。
D E V I C E L I S T结构被当作o p t v a l参数投递。这里有两个结构,一个针对Windows 98和Wi n d o w s
2 0 0 0,另一个针对Windows CE。这两个结构的格式如下:
Windows 98和Windows 2000结构与Windows CE结构之间的唯一区别是Windows 98和
Windows 2000 结构中包含一个W I N D O W S _ I R D A _ D E V I C E _ I N F O数组,该数组与W C E _
I R D A _ D E V I C E _ I N F O结构的数组相对应。条件性的# d e f i n e指令根据目标平台,声明
D E V I C E L I S T结构是正确的。同样,也有对I R D A _ D E V I C E _ I N F O结构的两个声明:
# d e f i n e指令根据目标平台,向正确的结构定义声明I R D A _ D E V I C E _ I N F O。
正如前面提到的那样,真正用于列举红外线设备的函数是带有I R L M P _ E N U M _ D E V I C E S
选项的g e t s o c k o p t函数。下面这一段代码,可把邻近的所有红外线设备I D列举出来:
第6章计地址家族和名字解析计计109
下载
在向g e t s o c k o p t调用投递一个D E V I C E L I S T结构之前,别忘了把n u m D e v i c e字段设成0。一
次成功列举会把n u m D e v i c e字段设成一个大于0的值,并把D e v i c e字段中I R D A _ D E V I C E _ I N F O
结构数量设为前一个值。同时,在实际应用中,为检查新使用的设备,可能会多次执行
g e t s o c k o p t。举个例子来说,一个很好的例子就是试着进行五次或少于五次的红外线设备查找。
方法很简单:在未成功列举之后,利用短期调用S l e e p,把该调用置入循环即可。
现在,大家已知道如何列举红外线设备,创建一个客户机或服务器就更简单了。同级的
服务器端更为简单,因为它像一个“普通”服务器。也就是说,不需要额外的步骤。创建
I r S o c k服务器的常见步骤如下;
1) 建立一个地址家族A F _ I R D A套接字和套接字类型S O C K _ S T R E A M。
2) 用服务器的服务名填写一个S O C K A D D R _ I R D A结构。
3) 利用套接字句柄和S O C K A D D R _ I R D A结构调用b i n d。
4) 利用套接字句柄和b a c k l o g边限调用l i s t e n。
5) 为接入客户机锁定一个a c c e p t调用。
建立客户机的步骤稍微有些复杂,因为必须先把红外线设备列举出来。建立I r S o c k客户
机所需步骤如下:
1) 建立地址家族A F _ I R D A套接字和套接字类型S O C K - S T R E A M。
2) 调用有I R L M P _ E N U M _ D E V I C E S选项的g e t s o c k o p t函数,列举所有可用的红外线设备。
3) 针对返回的每个设备,利用设备I D和准备连接的服务名填写一个SOCKADDR_ IRDA
结构。
4) 利用套接字句柄和S O C K A D D R _ I R D A结构,调用c o n n e c t函数。针对步骤3)中所填的
结构,重复步骤4),直到连接成功。
6.2.4 查询IAS
要知道特定服务是否在特定的设备上运行,有两种方法。第一种是真正与特定服务连
接;另一种是向I A S查询特定的服务名。两种方法都要求列举红外线设备,然后对每一个设备
进行查询直到达到目的或所有的设备都查完。执行查找是调用带有I R L M P _ I A S _ Q U E RY选项
的g e t s o c k o p t函数来完成的。再次提醒大家注意, I A S _ Q U E RY结构有两个,一个针对
Windows 98和Windows 2000,另一个针对Windows CE。各结构的格式如下:
110计计第二部分附Winsock API
下载
第6章计地址家族和名字解析计计111
下载
大家可看到,除了特定字符数组的长度不同之外,这两个结构的格式是差不多的。
要对特定服务的L S A P - S E L数有多少进行查询,很简单:把i r d a C l a s s N a m e字段设为L S A P -
S E L的属性字串,即I r D A : I r L M P : L s a p S e l,然后,把i r d a A t t r i b u t e N a m e字段设成准备查询的那
个服务名。除此以外,还必须用范围内的有效设备来设置i r d a D e v i c e I D字段。
6.2.5 创建套接字
红外线套接字的创建很简单。几乎不需要任何选项,这是因为I r S o c k只支持面向连接的数
据流。下面的代码说明了如何利用s o c k e t或W S A S o c k e t调用来建立红外线套接字。由于
Winsock 1.1的限制,必须采用Windows CE的s o c k e t。
如果不想因循守旧,可把I R D A _ P R O TO _ S I C K _ S T R E A M当作上面任何一个函数的协议参
数投递出去。但系统不需要这个协议参数,因为传输目录中只有一个地址家族A F _ I R D A条目。
指定A F _ I R D A会造成默认使用这个传输条目。
6.2.6 套接字选项
对I r D A来说,大多数S O _ s o c k e t选项都是没有意义的,只有S O _ L I N G E R得到了特别的支
持。I r S o c k特有的套接字选项当然也得到了支持,不过只限于地址家族A F _ I R D A套接字上。
我们将在第9章全面论述这些选项,第9章还对所有套接字选项及其参数进行了总结。
6.3 IPX/SPX
“互联网包交换”(I P X)协议是一个常见协议,一般为承担Novell NetWa r e客户机/服务
器联网服务的计算机所用。I P X提供两个进程间的无连接通信;因此,如果一个工作站发出一
个数据包,该协议无法保证这个数据包会准确无误地投递到目标地点。如果应用程序需要数
据投递保证,但仍坚持使用I P X,它就会选用一个比I P X高级的协议,比如说“顺序分组交换”
(S P X)和SPX II协议,这两个协议中, S P X包通过I P X发送。Wi n s o c k为应用程序提供了在
Wi n d o w s平台上通过I P X进行通信的能力(它们是Windows 95、Windows 98、Windows NT以
及Windows 2000),但没有提供Windows CE平台上通过I P X通信的能力。
6.3.1 编址
I P X网络、网段是用I P X路由器桥接在一起的。每个网段分配4字节的唯一地址号。当更多
的网段桥接在一起时, I P X路由器管理网段之间的通信,每个网段有唯一的网段号。连网时,
使用唯一的6字节网段号,这个号也往往是转接器的物理地址。一个节点(也就是一台计算机)
一般有一个或多个通信进程用I P X通信。I P X用套接字号来区分一个节点上的通信。
要用I P X进行Wi n s o c k客户机或服务器通信,必须建立S O C K A D D R _ I P X结构。该结构在
W s i p x . h头文件中定义,应用程序在包括Winsock 2.h文件之后还必须包括该文件。S O C K A D D R _
I P X结构如下定义:
s a _ f a m i l y字段应设为A F _ I P X值,s a _ n e t n u m字段是4字节的地址,代表I P X网络上网段号,
s a _ n o d e n u m字段是6字节的地址,代表节点计算机的物理地址, s a _ s o c k e t字段代表一个节点区
分I P X通信的套接字或接口。
6.3.2 创建套接字
利用I P X创建套接字提供了几种可能性。要打开I P X套接字,调用带有地址家族A F _ I P X、
套接字类型以及N S P R O TO _ I P X协议的s o c k e t函数或W S A S o c k e t函数即可,过程如下:
112计计第二部分附Winsock API
下载
注意,第三个参数协议是必须指定的,而且不能为0。这一点相当重要,因为该字段还可
用于设置特定I P X包的类型。
正如我们前面提到的那样, I P X利用数据报提供不可靠的无连接通信。如果一个应用需要
可靠的无连接通信,可采用比I P X高级的协议,比说S P X和SPX II。要做到这一点,把s o c k e t
和W S A S o c k e t调用的类型和协议字段分别设置成套接字类型S O C K _ S E Q PA C K E T或
S O C K _ S T R E A M和协议字段N S P R O TO _ S P X或N S P R O TO_SPX II即可。
如果指定了S O C K _ S T R E A M,系统就会把数据当作连续不断的字节流发送出去,没有消
息边界,这类似于T C P / I P中套接字的行为。另一方面,如果发送端发出2 0 0 0个字节,在这
2 0 0 0个字节全部到达接收端之前,接收端是不会返回任何消息的。对S P X和SPX II来说,这是
通过设置S P X头中的消息结束位来完成的。指定SOCK_ STREAM 时,要注意这个位,
Winsock recv和W S A R e c v调用在其收到这个位之前不会中止。如果指定S O C K _ S T R E A M时没
有注意到这个消息结束位,一旦接收端收到数据, r e c v就会中止,不管消息结束位设在哪里。
从发送端这一方来说(使用S O C K _ S E Q PA C K E T类型),如果发送的数据包小于一个完整的数
据包,消息结束位就会随这个包一起发送。如果发送的包大于一个完整的数据包,消息结束
位就只设在最后发送的那个包中,而不是每个包都有。
1. 绑定套接字
I P X应用通过b i n d把本地地址和套接字关联在一起时,不要在S O C K A D D R _ I P X结构中指
定网络号和节点地址。b i n d函数利用系统上可用的第一个I P X网络接口来填充这些字段。如果
一台计算机有多个网络接口(多址计算机),它就不必绑定特定的接口。Windows 95 、
Windows 98、Windows NT和Windows 2000提供一个虚拟内部网,不管它直接连接的物理网
络如何,该虚拟网中的每个接口都是可以抵达的。我们稍后将对内部网络编号进行详细论述。
应用成功绑定本地接口之后,便可利用下属代码段中的g e t s o c k n a m e函数获得本地网络编号和
节点编号的信息。
第6章计地址家族和名字解析计计113
下载
114计计第二部分附Winsock API
下载
2. 网络编号与内部网络编号
网络编号(通常称作外部网络编号)用于标识I P X中的网络段和I P X报在网络段之间的路
由选择。Windows 95、Windows 98、Windows NT以及Windows 2000平台特别突出了内部网
络编号,这个内部网络编号用于内部路由选择和对网间网(几个网络桥接在一起构成)上的
计算机进行唯一性标识。内部网络编号也称为“虚拟网号”,即内部网络编号对网间网中的另
一个(虚拟的)网络段进行标识。因此,如果一台计算机正在运行Windows 95、Windows 98、
Windows NT或Windows 2000,若打算为它配置一个内部网络编号, N e t Wa r e服务器或I P X路
由器就会在自己与那台计算机的路由之间另增一次跳跃。
在多址计算机情形下,内部虚拟网络用于某一特定目的。应用程序绑定本地网络接口时,不
应该指定本地接口信息,但需要把S O C K A D D R _ I P X结构的s a _ n e t n u m和s a _ n o d e n u m这两个字段设置
为0。这是因为I P X能够通过内部虚拟网络的使用,把一个数据包从任何一个外部网络路由到任何
一个本地网络接口。比如,即使你的应用程序明显地绑定网络A上的网络接口,而数据包却来自网
络B,内部网络编号就会使这个数据包在内部路由,这样,你的应用程序就收到这个数据包了。
3. 通过Wi n s o c k,设置I P X数据包的类型
在利用N S P R O TO _ I P X建立套接字时,Wi n s o c k允许应用程序指定I P X包的类型。I P X包内
的数据包类型字段表明这个I P X包提供或请求的服务类型。在N o v e l l网中,下面的I P X包类型
的定义是:
■ 0 1 h:路由信息协议(R I P)包。
■ 0 4 h:服务声明协议(S A P)包。
■ 0 5 h:顺序分组交换(S P X)包。
■ 11 h:N e t Ware Core协议(N C P)包。
■ 1 4 h:Novell NetBIOS的传输包。
要修改I P X包类型,只须把N S P R O TO_IPX + N指定为socket API的协议参数,n表示数据
包类型的编号。比如,要打开一个把包类型设为0 4 h(S A P包)的I P X套接字,可用下面的
s o c k e t调用:
4. 名字解析
大家可能知道,Wi n s o c k中的I P X定址有些麻烦,因为必须提供构成地址的多字节的网络
和节点编号。I P X使应用程序可以通过用户友好名找到相应服务,以此通过S A P协议获得I P X
网络中的网络编号、节点编号和端口编号。正如我们将在第1 0章看到的那样, Winsock 2利用
WSASetService API函数,提供了一个与协议无关的名字解析法。通过S A P协议, I P X服务器
应用可利用W S A A e t S e r v i c e在用户友好名下注册它们正在监听的网络编号、节点编号和端口
第6章计地址家族和名字解析计计115
下载
编号。Winsock 2还通过下面几个A P I函数提供了另一个与协议无关的名字解析法,它们是:
W S A L o o k u p S e r v i c e B e g i n、W S A l o o k u p S e r v i c e N e x t和W S A l o o k u p S e r v i c e E n d。
要执行自己的命名服务注册和查找,可以通过打开一个I P X套接字并指定S A P类型的方法
来完成。打开套接字之后,便可开始向I P X网络广播S A P包,以便在网络上注册和定位服务。
这要求大家深入了解S A P协议和掌握针对IPX SAP包解码的编程方面的基本知识。
6.4
ahhlian (2003-08-30 21:39:00)
这种资料哪里有下载,给一份!ahlain@sina.com
goujie (2003-08-30 21:41:00)
谢谢爱元元的哥哥,我先研究一下,一会给分,
谁有源码吗?如果可以的话,借小弟研究研究,谢谢。
爱元元的哥哥 (2003-08-30 21:48:00)
给个邮箱我,我发给你,ahlain,请收信
goujie (2003-08-30 21:50:00)
goujies@sohu.com
goujie@btamail.net.cn
谢谢
yubing8 (2003-08-30 21:52:00)
这么长,爱元元的哥哥有没有界面制作的源程序,上次你光发个好长好长的帖子却没有源程序,能不能发源程序给我
yubing8@163.net
爱元元的哥哥 (2003-08-30 21:55:00)
呵呵,我只是有这个资料,具体的代码我忘记放到哪里了,我这40G的代码库要整理一下了
爱元元的哥哥 (2003-08-30 21:56:00)
楼主,已经发给你了,这个资料其实很普通的
goujie (2003-08-30 22:01:00)
谢谢
goujie (2003-08-30 22:21:00)
如果谁有原码再给分!
低调一贱男 (2003-08-30 22:47:00)
其实如果和手机通讯基本上是不能用irsock的,起码我从来没有成功的操作过,因为irsock的api参数要你提供一个server的服务名,你可是很少有机会知道这个服务名的,我也一直在迷茫中,手机与电脑通讯,到底哪个是客户端,哪个是服务端,或者是要用类似udp的无连接数据发送,否则,若电脑是server端,手机怎么知道何时要与你连接,反之,电脑怎么知道服务名是多少,ir_addr是多少。
你可以尝试用ircomm,或者直接写串口,应该都可以实现,你用delphi 开发的话你还要自己封装winsock2的部分内容,delphi6,delphi7没有帮你封装,
低调一贱男 (2003-08-30 22:50:00)
上面的资料你可以去www.codestudy.net上下载一本 windows网络编程 看看,爱元元的哥哥也是从那里弄来的,这一段我研究了整整一个月
goujie (2003-09-04 9:57:00)
谢谢各位的回答,我在老美的网站上找到一个DELPHI 的例子,有需要的话给我MAIL 地址
爱元元的哥哥的回答最终被接受。