网络编程技术最新编辑.docx
- 文档编号:9175884
- 上传时间:2023-05-17
- 格式:DOCX
- 页数:36
- 大小:113.10KB
网络编程技术最新编辑.docx
《网络编程技术最新编辑.docx》由会员分享,可在线阅读,更多相关《网络编程技术最新编辑.docx(36页珍藏版)》请在冰点文库上搜索。
网络编程技术最新编辑
Windows网络编程
——Microsoft技术丛书
目录
第1章NetBIOS2
第2章重定向器5
第3章邮槽7
第4章命名管道9
第5章网络原理和协议15
第6章地址家族和名字解析21
第7章WinSock基础28
第8章WinSockI/O方法41
第9章套接字选项和I/O控制命令71
第11章多播81
第1章NetBIOS
NetBIOS——NetworkBasicInput/OutputSystem,网络基本输入/输出系统。
1.1MicrosoftNetBIOS
两个NetBIOS应用要通过网络进行正常通信,各自运行的机器至少安装一种两者通用的协议。
NetBEUI是一种不可路由协议。
但TCP/IP和IPX/SPX均属可路由协议。
1.1.1LANA编号
每个LANA编号对应于网卡及传输协议的唯一组合。
LANA编号的范围通常在0到9之间,除LANA0代表默认LANA之外,操作系统并不按某种固定的顺序来分配这些编号。
1.1.2NetBIOS名字
一个NetBIOS名字长度为16个字符。
针对每个LANA能够添加的名字的最大数量是254(编号从1到254,0和255由系统保留)。
NetBIOS名字共有两种类型:
唯一名字和组名。
1.1.3NetBIOS特性
NetBIOS提供了“面向连接”与“无连接”服务。
面向连接(面向会话)的服务允许两个客户机相互间建立一个会话——一种双向的通信数据流。
面向连接的服务可确保两个端点之间的任何数据都能准确无误地顺序传送。
“无连接”(数据报)服务中,事前不必先建立任何连接。
数据报服务既不能保证数据传输的可靠性,也不能保证数据包的传送顺序正确无误,但节省了建立连接所需的开销。
1.2NetBIOS编程基础
UCHARNetbios(PNCBpNCB);
用于NetBIOS的所有函数声明、常数等均在头文件nb30.h内定义。
需要连接的库是netapi32.lib。
pNCB对应于指向某个网络控制块(NCB)的指针。
typedefstruct_NCB{
UCHARncb_command;
UCHARncb_retcode;
UCHARncb_lsn;
UCHARncb_num;
PUCHARncb_buffer;
WORDncb_length;
UCHARncb_callname[NCBNAMSZ];
UCHARncb_name[NCBNAMSZ];
UCHARncb_rto;
UCHARncb_sto;
void(*ncb_post)(struct_NCB*);
UCHARncb_lana_num;
UCHARncb_cmd_cplt;
UCHARncb_reserve[10];
HANDLEncb_event;
}NCB;
进行任何Netbios调用之前,应先将这个NCB结构清零!
ncb_command:
指定命令编码以及表明NCB结构体是否被异步处理的标识。
ncb_retcodef:
指定命令的返回编码。
ncb_lsn:
表示本地会话编号,在指定环境中此编号唯一标识一个会话。
ncb_num:
指定本地网络名字编号。
ncb_buffer:
指定消息缓冲区。
(有发送信息、接收信息、接收请求状态信息三个缓冲区)。
ncb_length:
指定消息缓冲区的大小(字节)。
ncb_callname:
指定远程端应用程序的名字。
ncb_name:
指定应用程序可以识别的名字。
ncb_rto:
指定会话执行接收操作的超时时间。
ncb_sto:
设定发送操作的超时期限。
该值应设为500毫秒的一个整数倍数。
若为0,表示不存在超时限制。
该值是为NCBCALL和NCBLISTEN命令设置的,它们会影响后续的NCBSEND和NCBCHAINSEND命令。
ncb_post:
指定异步命令完成后需要调用的后例程的地址。
函数定义为:
voidCALLBACKPostRoutine(PNCBpncb);其中,pncb指向已完成命令的网络控制块。
ncb_lana_num:
指定LANA编号。
ncb_cmd_cpl:
指定命令完成标识。
ncb_reserve:
保留字段,必须为0。
ncb_event:
指向事件对象的句柄。
调用Netbios函数既可同步调用也可异步调用。
要异步调用命令,需要让NetBIOS命令同ASYNCH标志进行逻辑或运算。
如果指定了ASYNCH标志,就必须在ncb_post字段中指定一个后例程(PostRoutine),或必须在ncb_event字段中指定一个事件句柄。
1.3常规NetBIOS例程
在程序清单1-1中,LanaEnum函数列举指定系统上可用的LANA编号。
第二个函数是ResetAll。
重设只要求函数将ncb_command设为NCBRESET,并将ncb_lana_num设为它需要重设的LANA。
AddName函数的作用是将名字加入本地名字表。
AddGroupName的工作原理与AddName大致相同,但执行的命令则是NCBADDGRNAME。
DelName函数用于从名字表中删除一个NetBIOS名字。
Send与Recv函数用于数据的收发。
ncb_command可设为NCBSEND或NCBRECV。
Send和Recv还需要映射到ncb_buffer和ncb_length的参数。
函数Hangup和Cancel分别用于关闭已经建立的会话或取消一个尚未进行的命令。
可调用NetBIOS命令NCBHANGUP来从容地关闭一个建立的会话。
1.3.1会话服务器:
异步回调模型
程序清单1-2展示了服务器代码,利用了异步回调函数。
首先用LanaEnum列举所有可用的LANA编号,然后用ResetAll重设每个LANA。
服务器将自己的进程名TEST-SERVER-1增加到每个LANA编号。
服务器最关键的步骤是执行大量NCBLISTEN命令。
在程序清单1-2中,Listen函数会将ncb_post字段设成回调函数。
Listen函数将把ncb_name字段设为服务器进程的名字。
1.3.2会话服务器:
异步事件模型
事件模型更有效率。
事件模型服务器程序最开头的几步与回调服务器一致:
1)列举LANA编号。
2)重设每个LANA。
3)为每个LANA增加服务器的名字。
4)为每个LANA投放一个监听命令。
1.3.3NetBIOS会话客户机
程序清单1-4展示了客户机程序使用的源代码。
客户机首先采取一系列初始化步骤,为每个LANA编号的名字表增添自己的名字,然后执行一个异步连接命令。
主循环等候某个事件进入传信状态。
随后,代码遍历与执行连接命令对应的所有NCB结构。
它检查ncb_cmd_cplt的状态,如发现它设为NRC_PENDING(待决),代码就会取消异步命令;若命令完成,但NCB并不与传信的那个NCB相符,代码便会断开连接。
如果服务器正在对每个LANA进行监听扫描,同时客户机正在尝试在其每个LANA上建立连接,那么就可能出现成功建立多个连接的情况。
此时,代码会用NCBHANGUP命令关掉多余的连接。
1.4数据报的工作原理
“数据报”(Datagram)属于“无连接”通信。
发送方只需用目标NetBIOS名字为发出的每个包定址。
发送数据报有三种方式:
①让数据报抵达一个唯一名。
②将数据报发至一个组名。
③将数据报广播到整个网络。
用NCBDGSEND命令将数据报发给一个唯一名或一个组名;广播要用NCBDGSENDBC命令。
①将ncb_num字段设为从NCBADDNAME或NCBADDGRNAME命令返回的名字编号。
②将ncb_buffer设为包含了需要发出数据的缓冲区的地址,将ncb_lana_num字段设为一个特定的LANA编号。
③将ncb_callname设为目标NetBIOS名字(唯一名或组名)。
(发送广播数据报无此步骤)
当数据报抵达了某个客户机,但该客户机没有处在“待决”状态的接收命令,数据被抛弃,客户机也没有办法恢复未接收的数据。
这正是数据报通信最大的缺点。
但与面向连接相比,数据报的传送速度要快得多,因为没有错误检查、连接设置之类的开销。
数据报的接收也有三种方法。
头两种方法要用到NCBDGRECV命令。
可用NCBDGRECVBC命令接收广播数据报。
1.5其他NetBIOS命令
适配器状态命令——NCBASTAT
查找名字命令——NCBFINDNAME
第2章重定向器
I/O重定向:
通过网络访问某一设备,I/O请求必须通过网络转发给对应的远程设备。
在Windows中可将一个本地磁盘标识符映射或重定向到远程计算机上的一个目录。
应用程序要访问映射盘时,操作系统便将I/O请求自动重定向至一个设备,该设备叫作“重定向器”。
2.1通用命名规范
\\[服务器]\[共享名]\[路径]
例:
\\MyServer\MyShare\Sample.mp3
2.2多UNC提供者
MUP是一种资源定位器,负责选择具体的网络提供者以满足UNC连接请求。
MUP需要通过网络提供者,在以UNC名字为基础的文件及打印机I/O请求上提供服务。
2.3网络提供者
网络提供者是一种服务,通过网络硬件来访问位于远程计算机上的共享资源。
2.4重定向器简介
“重定向器”需要格式化服务请求消息,再将其发给远程计算机的重定向器服务器服务。
远程机器的重定向器服务器服务收到这个请求之后,会以本地I/O请求的方式满足这一请求。
2.5服务器消息块
在SMB数据结构中,包含三个基本组件:
命令代码、命令特有的以及用户数据。
2.6安全问题
Windows对像文件和目录这样的资源提供了本地和远程访问控制的能力。
若应用程序试图访问这些资源,操作系统便会检查该程序,看它是否有“访问权限”。
访问权限分为几种,最基本的包括读、写以及执行。
Windows是通过“安全描述符”以及“访问令牌”实现访问控制的。
2.6.1安全描述符
在安全描述符内包含了一个SECURITY_DESCRIPTOR结构,以及对应的安全信息:
■所有人安全标识符(SecurityIdentifier,SID)
■组SID
■授权访问控制列表(DiscretionaryAccessControlList,DACL)
■系统访问控制列表(SystemAccessControlList,SACL)
2.6.2访问令牌
用户登录WinNT系统成功,系统就会创建相应的访问令牌,并将该用户的SID分配给它。
2.7网络安全
MSNP重定向器负责不同计算机之间的资源访问,通过创建用户会话凭据的形式,在客户机与服务器之间建立一条安全通信链路。
2.8一个实例
使用MSNP重定向器,通过网络,Win32应用程序可分别使用CreateFile、ReadFile和WriteFile函数创建、访问以及修改文件。
第3章邮槽
通过邮槽,客户机进程可将消息传送或广播给一个或多个服务器进程。
邮槽最大的缺点是只允许从客户机到服务器建立单向数据通信。
邮槽最大的优点是它使客户机应用能够非常容易地将广播消息发送给一个或多个服务器应用。
3.1邮槽实施细节
邮槽是围绕Windows文件系统接口设计出来的。
邮槽必须依赖Windows重定向器,通过“邮槽文件系统”(MailslotFileSystem,MSFS)创建及标识邮槽。
3.1.1邮槽的名字
邮槽的命名规则:
\\Server\Mailslot\[path]name
服务器字符串部分可表示成一个小数点(.)、一个星号(*)、一个域名或一个服务器名字。
邮槽通过网络与计算机进行远程通信时,Windows文件系统服务依赖Windows重定向器,使用“服务器消息块”(SMB)协议,将数据从客户机传给服务器。
3.1.2消息的长度
表3-1邮槽消息的长度限制
传输方向
通过数据报进行“无连接”传输
进行“面向连接”的传输
Win9xWin9x
消息长度高达64KB
不支持
WinNT或Win2000WinNT或Win2000
消息长度必须≤424字节
消息长度必须>426个字节
WinNT或Win2000Win9x
消息长度必须≤424字节
不支持
Win9xWinNT或Win2000
消息长度必须≤424;多余的会被截去
不支持
3.1.3应用程序的编译
包含winbase.h,链接Kernel32.lib。
3.1.4错误代码
调用失败时,CreateFile和CreateMailslot返回INVALID_HANDLE_VALUE。
3.2基本客户机/服务器
服务器进程负责创建一个邮槽。
邮槽客户机进程则负责打开邮槽的实例。
3.2.1邮槽服务器的详情
编写一个基本服务器应用的步骤:
1)用函数CreateMailslot创建一个邮槽句柄。
2)调用函数ReadFile,使用已有的邮槽句柄从任何客户机接收数据。
3)用函数CloseHandle关闭邮槽句柄。
3.2.2邮槽客户机的详情
编写基本的客户机应用的步骤:
1)使用函数CreateFile打开指向用于传送数据邮槽的引用句柄。
2)调用函数WriteFile向邮槽写入数据。
3)数据的写入完成后,用函数CloseHandle关闭打开的邮槽句柄。
3.3其他邮槽API
GetMailslotInfo、SetMailslotInfo。
3.4平台和性能问题
在Win9x平台上,邮槽存在着一些限制:
“8.3字符名字限制”、不能取消“凝结”的I/O请求以及由于超时引起的内存废弃。
第4章命名管道
命名管道实际上建立起一个简单的客户机/服务器数据通信体系。
4.1命名管道的实施细节
4.1.1命名管道命名规范
命名管道的标识采用UNC格式:
\\server\Pipe\[path]name
4.1.2字节模式与消息模式
字节模式:
消息以连续的字节流的形式在客户机与服务器之间流动。
消息模式:
客户机和服务器通过一系列不连续的数据单位进行数据的收发。
4.1.3应用程序的编译
必须在程序文件中包含winbase.h头文件,并链接Kernel32.lib库。
4.1.4错误代码
CreateFile和CreateNamedPipe失败时返回INVALID_HANDLE_VALUE。
4.2客户机与服务器的基础
4.2.1服务器的细节★
创建命名管理服务器的步骤:
1)用CreateNamedPipe创建一个命名管道实例句柄;
2)用ConnectNamedPipe在命名管道实例上监听客户机连接请求;
3)分别使用ReadFile和WriteFile从客户机接收数据或将数据发给客户机;
4)用DisconnectNamedPipe关闭命名管道连接;
5)用CloseHandle关闭命名管道实例句柄。
程序清单4-1—简单的命名管道服务器(Server.cpp)。
4.2.2高级服务器的细节
要想同时控制多个管道实例,服务器必须使用多线程或使用异步Win32I/O机制。
1.线程
程序清单4-2—在Win32环境中使用线程技术开发的高级命名管道服务器(Threads.cpp)。
2.重叠式I/O
工作原理:
向函数传递一个OVERLAPPED结构,然后使用函数GetOverlappedResult,从原来那个OVERLAPPED结构中取得I/O请求的结果。
程序清单4-3—使用Win32重叠式I/O技术开发的高级命名管道服务器(Overlap.cpp)。
3.安全模拟
服务器的线程要在客户机的安全环境中执行,需要设置一个安全模拟级别。
4.2.3客户机的细节★
1)调用WaitNamedPipe等候一个命名管道实例可被使用。
2)调用CreateFile建立与命名管道的连接。
3)调用WriteFile和ReadFile分别向服务器发送数据或从服务器接收数据。
4)调用CloseHandle关闭打开的命名管道。
程序清单4-4—简单的命名管道客户机(Client.cpp)。
4.3其他API调用
CallNamedPipe、TransactNamedPipe、GetNamedPipeHandleState、SetNamedPipeHandleState、GetNamedPipeInfo、PeekNamedPipe。
第5章网络原理和协议
5.1协议的特征
5.1.1面向消息
面向消息:
传输协议把每个离散的写命令当作一条独立的消息在网上传送。
5.1.2面向连接和无连接
面向连接的服务在进行数据交换之前,必须在通信双方建立一条通信信道。
无连接协议并不关心接收端是否正在收听。
5.1.3可靠性和次序性
可靠性保证了发送端发出的每个字节都能到达既定的接收端。
次序性是指数据到达接收端的顺序。
5.1.4从容关闭
在从容关闭的过程中,一方开始关闭通信会话,但另一方仍然可以读取线上或网络堆栈上挂起的数据。
如果使用TCP协议,连接双方都必须执行一次关闭,以便完全中断连接。
5.1.5广播数据
一般情况下,路由器不会传送广播包。
5.1.6多播数据
多播发送的数据有一个或多个接收端接收。
IP协议下,多播是广播的一种变形。
视频会议应用常常使用多播。
5.1.7服务质量
QoS是用来解决网络延迟和阻塞等问题的一种技术。
5.1.8部分消息
多数不支持部分消息的协议都会丢弃不完整的数据报。
5.1.9路由选择的考虑
可路由或不可路由。
5.1.10其他特征
字节序和最大传输单元。
5.2支持的协议
5.2.1支持的Win32网络协议
表5-1提供了大部分实用协议及各协议支持的一些行为。
5.2.2WinCE网络协议
WinCE只支持TCP/IP协议与WinSock1.1规格。
5.3WinSock2协议信息
可调用WSAEnumProtocols或EnumProtocols函数获得系统中安装的网络协议信息。
通常需要两次调用WSAEnumProtocols函数才能获取特定协议的信息。
启动WinSock库的函数:
intWSAStartup(WORDwVersionRequested,LPWSADATAlpWSAData);
卸载WinSock库的函数:
intWSACleanup(void);
5.4Windows套接字
套接字是一个指向传输提供者的句柄。
在Win32中,套接字的类型为SOCKET。
建立套接字的函数:
SOCKETWSASocket(intaf,inttype,intprotocol,LPWSAPROTOCOL_INFOlpProtocolInfo,
GROUPg,DWORDdwFlags);
SOCKETsocket(intaf,inttype,intprotocol);
5.5具体平台的问题
5.6选择适当的协议
如果从头开发应用程序,TCP/IP是首选协议。
TCP/IP是最安全的选择。
第6章地址家族和名字解析
6.1IP
6.1.1TCP
TCP能提供可靠的数据传输。
在利用TCP进行通信时,源和目标之间会建立一个虚拟连接。
6.1.2UDP
UDP不保证可靠的数据传输。
6.1.3定址
在WinSock中,可以通过SOCKADDR_IN结构来指定IP地址和服务端口信息。
structsockaddr_in{shortsin_family;
unsignedshortsin_port;
structin_addrsin_addr;
charsin_zero[8];};
端口号分为三类:
“已知”端口:
0~1023
已注册端口:
1024~49151
动态或私用端口:
49152~65535
inet_addr函数可将一个点式IP地址转换成一个32位的无符号长整数:
unsignedlonginet_addr(constcharFAR*cp);
1.特殊地址
INADDR_ANY允许服务器应用监听每个网络接口上的客户机活动。
INADDR_BROADCAST用于在一个IP网络中发送广播UDP数据报。
2.字节排序
Little-Endian:
低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。
Big-Endian:
高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。
网络字节序:
TCP/IP协议中使用的字节序。
将一个数从主机字节顺序转换成网络字节顺序的4个函数:
u_longhtonl(u_longhostlong);
intWSAHtonl(SOCKETs,u_longhostlong,u_longFAR*lpnetlong);
u_shorthtons(u_shorthostshort);
intWSAHtons(SOCKETs,u_shorthostshort,u_shortFAR*lpnetshort);
将网络字节顺序转换成主机字节顺序的4个函数:
u_longntohl(u_longnetlong);
intWSANtohl(SOCKETs,u_longnetlong,u_longFAR*lphostlong);
u_shortntohs(u_shortnetshort);
intWSANtohs(SOCKETs,u_shortnetshort,u_shortFAR*lphostshort);
利用inet_addr和htons函数来创建SOCKADDR_IN结构:
SOCKADD_INInternetAddr:
INTnPortId=5150;
InternetAddr.sin_family=AF_INET;
InternetAddr.sin_addr.s_addr=Inet_addr("136.149.3.29");
InternetAddr.sin_port=htons(nPortId);
6.1.4创建套接字
s=socket(AF_INET,SOCK_STREAM,0);
s=WSASocket(AF_INET,SOCK_STREAM,0,NULL,0,WSA_FLAG_OVERLAPPED);
要利用UDP协议打开IP套接字,只须用SOCK_DGRAM代替函数中的SOCK_STREAM。
6.1.5名字解析
gethostbyname、WSAAsyncGetHostByName函数从主机数据库中返回与指定的主机名对应的主机信息。
gethostbyaddr、WSAAsynGetHostByName可获得与IP网络地址相应的主机信息。
调用getservbyname或WSAAsyncGetServByName函数可从名为services的文件中获得已知服务的端口号。
6.2红外线套接字
红外线套接字称为IrSoc
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 网络 编程 技术 最新 编辑