版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、C语言实的串行通信接口程序摘要该文介绍了Skets通信原理,从程序员角度着重讨论了indsSkets为支持异步通信对Skets的功能扩大,并给出了应用indsSkets实现网络实时通信的一个程序实例。关IB公司于1994年4月推出的TP/IPfrDSV2.1.1所提供的开发软件包PrgraersTlKit不仅带有DS下网络编程接口,而且提供了inds下网络异步通信接口INSK。一、Sket网络编程原理Sket是BSDUNIX提供的网络应用编程接口,它采用客户机/效劳器的通信机制,使网络客户机方和效劳器方通过Sket实现网络之间的连接和数据交换。Sket提供了一系列的系统调用,使用这些系统调用可
2、以实现TP、UDP、IP和IP等多种网络协议之间的通信。Sket有三种主要类型:streaskets,datagraskets和raskets。Streasket接口定义了一种可靠的面向连接的效劳,它实现了无过失无重复的顺序数据传输。它通过内置的流量控制解决了数据的拥塞,应用程序可以发送任意长度的数据,将数据当作字节流。Datagrasket接口定义了一种无连接的效劳,数据通过互相独立的包进展传输,包的传输是无序的,并且不保证是否出错、丧失和重复。包长度是有限的(隐含长度为8192字节,最大长度可设为32768字节)。Rasket接口允许对低层协议如IP和IP的直接存取,它主要用于新的网络协议
3、实现的测试等。下面我们通过一个面向连接的传输发生的典型情况来说明sket网络通信的实现。由图我们可以看出,客户机和效劳器的关系不是对称的。效劳器首先启动,然后在某一时间启动客户机与效劳器建立连接。效劳器和客户机开场都必须用调用sket()建立一个套接字(sket),然后效劳器调用bind()将套接字与一个本地网络地址捆扎在一起,再用调用listen()使套接字处于一种被动的准备接收状态,同时规定它的恳求队列长度,之后效劳器就可以调用aept()来接收连接了。客户机在建立套接字之后,便可以通过调用nnet()和效劳器建立连接。连接建立后,客户机和效劳器之间就可以通过连接发送和接收数据(调用rea
4、d()和rite()。最后,待数据传送完毕,双方调用lse()关闭套接字。T8S10700.GIF;面向连接的协议实现的Sket调用图二、INSK对Sket的扩大BSDSket支持阻塞(blking)和非阻塞(nn-blking)两种工作方式。在阻塞方式下,nnet()、aept()、read()和rev()等调用在执行时都处于阻塞状态直到它成功或出错返回。在非阻塞方式下,这些调用是立即返回的,但是它们是否完成得靠查询才能知道。对于inds这种非抢先多任务操作系统来说,这两种工作方式都是难以承受的,为此,INSK在尽量与BSDSket保持一致的前提下,又对它作了必要的扩大。INSK对BSDSk
5、et的扩大主要是在基于消息、对网络事件的异步存取接口上。表1列出了INSK扩大的函数功能。从表1可以看出,INSK的扩大功能可以分为如下几类。(1)异步选择机制异步选择函数SAAsynSelet()允许应用程序提名一个或多个感兴趣的网络事件,所有非阻塞的网络I/例程(如send()和resv(),不管它是已经使用还是即将使用,都可作为SAAsynSelet()函数选择的候眩当被提名的网络事件发生时,inds应用程序的窗口函数将收到一个消息,消息附带的参数指示被提名过的某一网络事件。T8S10701.GIF;表1INSK扩大函数功能(2)异步恳求例程异步恳求例程允许应用程序用异步方式获取恳求的信
6、息,如SAAsynGetXByY()类函数允许用户恳求异步效劳,这些功能在使用标准Berkeley函数时是阻塞的。函数SAanelAsynRequest()允许用户终止一个正在执行的异步恳求。(3)阻塞处理方法INSK在调用途于阻塞时进入一个叫“Hk的例程,它负责处理inds消息,使得inds的消息循环可以继续。INSK还提供了两个函数(SASetBlkingHk()和SAUnhkBlkingHk()让用户可以设置和取消自己的阻塞处理例程。另外,函数SAIsBlking()可以检测调用是否阻塞,函数SAanelBlkingall()可以取消一个阻塞的调用。(4)出错处理为了和以后的多线索环境(
7、如indsNT)兼容,INSK提供了两个出错处理函数SAGetLastErrr()和SASetLastErrr()来获取和设置本线索的最近错误号。(5)启动与终止INSK的应用程序在使用上述INSK函数前,必须先调用SAStartup()函数对indsSketsDLL进展初始化,以协商INSK的版本支持,并分配必要的资源。在应用程序退出之前,应该先调用函数SAleanup()终止对indsSketsDLL的使用,并释放资源,以利下一次使用。在这些函数中,实现inds网络实时通信的关键是异步选择函数SAAsynSelet()的使用,其原型如下:intPASALFARSAAsynSelet(SKE
8、Ts,HNDhnd,unsignedintsg,lnglEvent);它恳求indsSketsDLL在检测到在套接字s上发生的lEvent事件时,向窗口hnd发送一个消息sg。它自动地设置套接字s处于非阻塞工作方式。参数lEvent由表2所列事件的一个或多个组成。T8S10702.GIF;表2异步选择网络事件例如,我们要在套接字s读准备好或写准备好时接到通知,可以使用下面的语句:r=SAAsynSelet(s,hnd,sg,FD-READ|FD-RITE);当套接字s上被提名的一个网络事件发生时,窗口hnd将收到消息sg,变量lPara的低字指示网络发生的事件,高字指示错误码。应用程序就可以通
9、过这些信息来决定自己的下一步动作。三、网络实时通信的实现我们来设计一个简单的基于连接的点对点网络实时通信程序。效劳器首先启动,它建立套接字之后等待客户机的连接;客户机在启动后,建立套接字,然后和效劳器建立连接;连接建立后,客户机通过连接给效劳器发送一段数据,效劳器接收后又将它发送回来,客户机再发送,如此循环,直至用户命令客户机退出或网络出错;客户机关闭连接和套接字后退出,效劳器在检测到连接关闭后,关闭套接字自动完毕。我们的实例是UNIX下基于BSDSket的效劳器程序和inds下基于INSK的客户机程序之间的通信。效劳器在主机UNIX下直接运行,前台和后台均可;客户机在inds下运行,带一个参
10、数,即主机的名字。如inlientrs6000,rs6000是在HSTS文件中已定义好的主机名。我们先看客户机程序,首先定义几个宏、菜单资源和局部全局变量。程序1:局部inds程序源代码(宏、菜单和变量)#defineUSERPRT3333/*用户定义端口号*/#defineID-START101/*“启动菜单项标志*/#defineID-EXIT102/*“退出菜单项标志*/#defineU-SK-USER+0 x100/*用户定义网络消息*/lientenuENU/*客户机菜单*/BEGINPPUPServerBEGINENUITEStart.,ID-STARTENUITEStp,ID-S
11、TPENDEND#inludeinsk.h/*必须包含insk.h头文件*/HANDLEhInst;harserver-address=0;/*效劳器地址缓冲区*/harbuffer;/*接收发送缓冲区*/harFAR*lpBuffer=buffer;SKETs=0;/*套接字*/strutskaddr-indst-addr;/*目的地址*/struthstent*hstaddr;/*主机地址*/struthstenthstn;intunt=0;/*发送接收循环计数器*/客户机程序的窗口主函数很简单,它在注册窗口类、建立窗口后,只是给主窗口函数发送一个用户消息,然后就进入inds消息处理循环。
12、程序2:局部inds程序源代码(窗口主函数)intPASALinain(HANDLEhInstane,HANDLEhPrevInstane,LPSTRlpdLine,intndSh)HNDhnd;SGsg;lstrpy(LPSTR)server-address,lpdLine);/*取主机名字*/if(!hPrevInstane)if(!InitAppliatin(hInstane)return(FALSE);hInst=hInstane;hnd=reateind(lientlass,indsEHlient,S-VERLAPPEDIND,-USEDEFAULT,-USEDEFAULT,-USE
13、DEFAULT,-USEDEFAULT,NULL,NULL,hInstane,NULL);if(!hnd)return(FALSE);Shind(hnd,ndSh);Updateind(hnd);/*给主窗口函数发送-USER消息*/Pstessage(hnd,-USER,(PARA)0,(LPARA)0);hile(Getessage(sg,NULL,NULL,NULL)Translateessage(sg);Dispathessage(sg);return(sg.Para);主窗口函数lientPr是程序的主要局部,它处理相关的消息:在接到消息-USER后,它调用函数SAStartup()
14、初始化indsSketsDLL,并检查其版本号,然后通过主机名获取主机地址;在接到消息-AND时,假如是命令ID-START,那么调用子程序lient()建立套接字,并试图和效劳器建立连接,假如是命令ID-STP,那么调用函数SAleanup()终止indsSketsDLL,并发出终止应用程序的消息;在接到消息U-SK时,它根据参数lPara指示的网络事件,进展相应的操作,然后选择下一个期望的网络事件。程序3:局部inds程序源代码(主窗口函数)lngFARPASALlientPr(HNDhnd,unsignedessage,UINTPara,LNGlPara)intlength,i;SADA
15、TAsaData;/*描绘indsSkets实现细节的数据构造*/intStatus;sith(essage)ase-USER:Status=SAStartup(0 x101,saData);if(Status!=0)AlertUser(hnd,SAStartup()failed);PstQuitessage(0);if(LBYTE(saData.Versin)!=1|HIBYTE(saData.Versin)!=1)/*如今支持的版本是INSK.DLL1.1*/AlertUser(hnd,SAStartup()Versinntath);SAleanup();PstQuitessage(0);
16、hstaddr=gethstbynae(server-address);if(hstaddr=NULL)AlertUser(hnd,gethstbynaeERRR);SAleanup();PstQuitessage(0);epy(hstn,hstaddr,sizef(struthstent);break;ase-AND:sith(Para)aseID-START:if(!lient(hnd)lsesket(s);AlertUser(hnd,StartFailed);break;aseID-STP:SAleanup();PstQuitessage(0);break;break;aseU-SK:s
17、ith(lPara)aseFD-NNET:/*网络事件:连接建立*/if(!set-selet(hnd,FD-RITE)/*选择:期望发送*/lsesket(s);break;aseFD-READ:/*网络事件:读准备好*/if(!reEive-pkt(hnd)/*接收数据*/AlertUser(hnd,ReeivePaketFailed);lsesket(s);break;if(!set-selet(hnd,FD-RITE)/*选择:期望发送*/lsesket(s);break;aseFD-RITE:/*网络事件:写准备好*/fr(i=0;i1024;i+)buffer=(har)A+i%2
18、6;length=1024;if(!(send-pkt(hnd,length)/*发送数据*/AlertUser(hnd,PaketSendFailed);lsesket(s);break;if(!set-selet(hnd,FD-READ)/*选择:期望接收*/lsesket(s);break;aseFD-LSE:/*网络事件:连接关闭。操作:停顿异步选择*/if(SAAsynSelet(s,hnd,0,0)=SKET-ERRR)AlertUser(hnd,SAAsynSeletFailed);AlertUser(hnd,Skethasbeenlsed);break;default:/*网络
19、出错那么警告,其他事件忽略*/if(SAGETSELETERRR(1Para)!=0)AlertUser(hnd,SketReprtFailure);lsesket(s);break;break;break;ase-DESTRY:lsesket(s);/*关闭窗口前应该关闭套接字,并*/SAleanup();/*终止indsSketsDLL*/PstQuitessage(0);break;default:return(DefindPr(hnd,essage,Para,lPara);return(NULL);程序4:局部inds程序源代码(子程序)BLlient(HNDhnd)/*客户机子程序*
20、/if(!ake-skt(hnd)/*建立套接字*/return(FALSE);if(!set-selet(hnd,FD-NNET)/*设置异步连接*/return(FALSE);if(!nnet-skt(hnd)/*建立连接*/return(FALSE);return(TRUE);BLreeive-pkt(HNDhnd)/*接收数据子程序*/HDd;intlength;int11,12,13;harlinel,line2,line3;unt+;/*循环计数器加1*/if(length=rev(s,lpBuffer,1024,0)=SKET-ERRR)return(FALSE);/*假如接收数
21、据出错,那么返回FALSE*/if(length=0)/*接收数据长度为零,表示连接中断*/return(FALSE);if(d=GetD(hnd)/*接收数据成功,显示信息*/11=sprintf(LPSTR)line1,TPEhlientN.%d,unt);12=sprintf(LPSTR)line2,Reeived%dbytes,length);13=sprintf(LPSTR)line3,Thseare:%,%,%,%,%,%,buffer,buffer,buffer,buffer,buffer,buffer);Textut(d,10,2,(LPSTR)linel,11);Textut
22、(d,10,22,(LPSTR)line2,12);Textut(d,10,42,(LPSTR)line3,13);ReleaseD(hnd,d);return(TRUE);BLset-selet(HNDhnd,lnglEvent)/*异步选择子程序*/if(SAAsynSelet(s,hnd,U-SK,lEvent)=SKET-ERRR)AlertUser(hnd,SAAsynSeletFailed);return(FALSE);return(TRUE);BLake-skt(HNDhnd)/*建立套接字子程序*/if(s=sket(AF-INET,sk-type,0)=INVALID-SKE
23、T)AlertUser(hnd,SketFailed);return(FALSE);return(TRUE);BLnnet-skt(HNDhnd)/*建立连接子程序*/eset(vid*)dst-addr,sizef(dst-addr),0);dst-addr.sin-faily=AF-INET;dst-addr.sin-prt=htns(USERPRT);dst-addr.sin-addr.s-addr=*(unsignedlng*)hstn.h-addr-list);if(nnet(s,(strutskaddr*)dst-addr,sizef(dst-addr)=SKET-ERRR)Ale
24、rtUser(hnd,nnetFailed);return(FALSE);return(TRUE);BLsend-pkt(HNDhnd,intlen)/*发送数据子程序*/intlength;if(length=send(s,lpBuffer,len,0)=SKET-ERRR)return(FALSE);elseif(length!=len)AlertUser(hnd,SendLengthNTath!);return(FALSE);return(TRUE);我们用最简单的语句编制一个UNIX下基于BSDSKET的效劳器程序,它在建立连接后,只负责将收到的数据发回去,在连接断开后,效劳器关闭套接
25、字返回。要编制在inds下的效劳器程序,可参照客户机程序,使用INSK的异步选择机制。程序5:UNIX下效劳器程序源代码/*TP/IP必要的头文件*/#inludesys/types.h#inludenetinet/in.h#inludesys/sket.h#inludearpa/inet.h#defineUSERPRT3333/*用户定义端口号,与客户机一样*/#defineHST-IP-ADDR166.111.8.80/*我们的主机地址*/ain(intarg,har*argv)harbuf;/*bufferfrsendingandreEivingdata*/strutskaddr-inl
26、ient;/*lientaddressinfratin*/strutskaddr-inserver;/*serveraddressinfratin*/ints;/*sketfraeptingnnetins*/intns;/*sketnnetedtlient*/intnaelen;/*lengthflientnae*/intpktlen;/*lengthfpaketreeivedrsended*/if(s=sket(AF-INET,SK-STREA,0)0)perrr(Sket();return;/*Bindthesketttheserveraddress.*/bzer(har*)server,sizef(server);server.sin-len=sizef(strutskaddr-in);server.sin-faily=AF-INET;server.sin-prt=htns(USERPRT);server.sin-addr.s-addr=INADDR-ANY;if(bind(s,(strutskaddr*)server,sizef(server)0)perrr(Bind();return;/*Listenfrnnetins.Speifythebaklgas
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025-2030年中国光学仪器行业商业模式创新战略制定与实施研究报告
- 2025-2030年中国幼小衔接教育行业商业模式创新战略制定与实施研究报告
- 2025-2030年中国旅游行业并购重组扩张战略制定与实施研究报告
- 2025-2030年中国休闲餐饮行业全国市场开拓战略制定与实施研究报告
- 2025-2030年中国知识密集型服务行业营销创新战略制定与实施研究报告
- 2025-2030年中国钽电容器行业全国市场开拓战略制定与实施研究报告
- 新形势下智能门锁行业转型升级战略制定与实施研究报告
- 德州黑陶品牌推广调研
- 单位办公室2025年工作要点
- 护肝药品知识培训课件
- 梁平法制图规则及钢筋翻样讲解
- 乙肝 丙肝培训课件
- 2024届湖北省武汉实验外国语学校数学七上期末统考模拟试题含解析
- 基于深度学习的网络钓鱼邮件识别技术研究
- 融资成本视角下的船舶融资租赁模式研究
- 感冒中医理论知识课件
- 2023年希望杯数学培训100题-六年级(含答案)
- 一年级科学人教版总结回顾2
- 个人住房贷款提前还款月供及节省利息EXCEL计算
- 第五单元《圆》教材解析-人教版数学六年级上册
- 患者突发昏迷应急预案演练脚本-
评论
0/150
提交评论