当前位置:文档之家› 第4 期 李红军 等 Windows Sockets 网络编程 71

第4 期 李红军 等 Windows Sockets 网络编程 71

第4 期 李红军  等 Windows Sockets 网络编程 71
第4 期 李红军  等 Windows Sockets 网络编程 71

第13卷 第4期武 汉 科 技 学 院 学 报V o1.13N o.4 2000年 12月 JOURNA L OF W UH AN I NSTIT UTE OF SCIE NCE AND TECH NO LOGY Dec. 2000

Windows Sockets网络编程

李红军 赵玉娇 赵 伟

(机械系) (图书馆) (教务处)

摘 要 在对Windows S ockcts网络编程作简要介绍的基础上,对在Visual C++6.0环境下如何进

行网络编程以及如何使用多线程进行网络编程作了介绍和示范。

关键词 网络 套接字 阻塞 多线程

中图分类号 TP393

1 WindowsSockets简介

Windows s ockets(简称Wins ock)是微软的窗口系统结构(W OS A)的一部分。它是起源于UNIX上的Berkeley S oftware Distribution(BS D)版本的套接字、并为Windows进行了专门地扩展。Internet是在UNIX系统上发展起来的,在UNIX上有许多成熟的编程接口,其中最通用的是一种叫做s ockets(套接字)的接口。套接字的实质是通信端点的一种抽象,它提供一种发送和接收数据的机制。网络软件商为Windows开发一套标准的、通用的TCP/IP编程接口,并使之类似于UNIX下的s ockets,这就是Windows s ockets;Windows s ocket的实现一般都由两部分组成:开发组件和运行组件。开发组件是供程序员开发Wins ock应用程序使用的、它包括介绍Wins ock 实现的文档、Wins ock应用程序接口(API)引入库和一些头文件。运行组件是Wins ock应用程序接口的动态连接库(D LL),文件名为Wins ock.D LL,应用程序在执行时通过装入它来实现网络通信功能。

最初,Wins ocket1.1版是专门为Internet设计的,现在的2.x版己经不再限于Internet和TCP/IP协议,它通过提供扩展的API编程接口,把自己的应用范围扩大到现存的和正在出现的各种网络和协议,包括PST N、IS DN、无线网、所有的局域网协议、异步传输模式AT M等等;并且允许应用程序对所建立连接的可靠性、冗余度和带宽进行控制。由此可见,Wins ock有着广泛的应用。

Windows s ockets是Windows下网络编程的规范。这套规范是Windows下得到广泛应用的、开放的、支持多种协议的网络编程接口。它定义并记录了如何使用API与Internet协议族(IPs、通常我们指的是TCP/IP)连接,尤其要指出的是所有的Windows s ockets实现都支持流套接字和

收稿日期:2000-8-25

作者简介:李红军,男,(1974-);武汉,武汉科技学院(430073)

数据报套接字。当我们为客户机/服务器开发一个特殊的应用程序时,我们可以通过套接字来交换我们的数据结构和数据报,以完成应用程序之间的通信。应用程序调用Wins ock 的API 实现相互之间的通讯。Wins ock 又利用下层的网络通讯协议功能和操作系统调用实现实际的通讯工作。它们之间的关系如图1所示:

应用程序1 应用程序2

ξψ ξψ网络编程界面,例如Windows S ockets

ξ ψ网络通讯协议服务界面,例如T CP/IP ξ ψ操作系统,例如Windows 98,Windows NT ,D os 6.22

ξ ψ

物理通讯介质

图1 应用程序与Wins oCk 关系图2 套接字的两种主要形式

在Windows 套接字中,它主要有两种形式:数据报套接字(Datagram s ocket )和流式套接字(Stream s ocket )。流式(也称面向连接方式)套接字采用的是TCP 协议,它提供了双向的,有序的,无重复并且无记录边界的数据流服务。在这种方式下,两个通讯的应用程序之间先要建立一种虚拟的连接。流方式的特点是:通讯可靠,对数据有校验和重发的机制,通常用来作数据文件的传输如ftp ,telnet 等,适合于大量数据的传输。

数据报套接字采用的是UDP 协议,它建立在IP 协议上,提供无连接数据报传输,支持双向的数据流,但并不保证是可靠、有序、无重复的。也就是说,一个从数据报套接字接收信息的进程有可能发现信息重复了,或者和发出时的顺序不同。数据报文方式由于取消了重发校验机制,能够达到较高的通讯速率,可以用作一些对数据可靠性要求不高的遮讯,如实时的语音、图象传输等。另外,数据报套接字支持广播发送,使用sets ockopt ()函数可以使指定的套接字发送广播消息。相比之下,流式套接字不支持广播发送。

是使用流式套接字还是使用数据报套接字,对通信效率影响较大。在编程中,流式套接字与数据报套接字是有区别的。在流式套接字中,服务器首先启动,遮过调用s ocket ()建立一个套接字,然后调用bind ()将该套接字和本地网络地址联系在一起,再调用listen ()使套接字做好侦听的准备,并规定它的请求队列的长度,之后就调用accept ()来接收连接。客户在建立套接字后就可调用connect ()和服务器建立连接。连接一旦建立,客户机和服务器之间就可以调用receive ()和send ()来发送和接收数据。最后,待数据传送结束后,双方调用close ()关闭套接字,如图2所示。

与流式套接字不同的是,在数据报套接字中,服务器不调用accept (),客户机不调用connect ()。在发送数据之前,客户机和服务器之间尚未建立完整相关。无连接服务器通过s ockct ()和bind ()建立了本地半相关,在传输数据之前,无连接的两个端点已建立起来,分别以一个本地s ocket 号和信宿端s ocket 地址。于是,一个完整的相关在数据收发过程中动态地建立起来,实现无连接客户和服务器彼此识别。如图3所示:

17第4期 李红军 等: Windows S ockets 网络编程

3 在VC 下开发套接字程序

在实际编程中,我们一般采用面向对象技术,特别采用消息驱动机制实现多任务的Windows 编程思想,VC 由于它的强大的功能而被广泛采用。

3.1 在VC 下开发套接字程序的基本步骤

在VC ++6.0中,我们可以用Windows s ockets API 来编写网络程序,其特点是十分灵活,可以充分利用众多的Windows s ockets API 函数,相比之下编程比较烦琐。另外我们可以使用MFC 封装的C AsyncS ocket 和CS ocket 两个类来进行网络编程,它把与套接字有关的Windows

消息转换为回调函数。C AsyncS ocket 类比CS ocket 更加面向低层,它提供的低级接口几乎与WinS ocket API 调用直接对应,使用比较灵活,但它对编程人员的要求也高,需要对网络了解得更多。CS ocket 是C AsyncS ocket 的导出类,通过MFC 中的C Archive 类的对象提供了更高层次的抽象,它封装了s ocket 实现中的许多细节,并将s ocket 与C Archive 相结合,使用它与使用MFC 中的文档串行化协议相类似,使用便利。CS ocket 编程的主要步骤如下;

(1)构造套接字对象。

(2)使用该对象构造基本的套接字。对于CS ocket 客户端对象,使用缺省参数Creat ;对于CS ockct 服务器对象,应指明一个端口号作为Create 的一个参数,用于监听。

(3)建立客户端CS ocket ,调用C AsyncS ocket ::C onnect ()建立与服务器端的连接。服务器端套接字调用C AsyncS ocket ::Listen ()监听,并在收到客户端请求后调用C AsyncS ocket ::Accept ()。

(4)构造CS ocketFile 对象,并使Cs ocket 对象与之关联。

(5)构造C Archive 对象,用于接收或发送数据。

(6)使用C Archive 对象来进行客户端与服务器端的套接字通信。

(7)删除C Archive 、CS ocketFile 、CS ocket 对象。流程图如图4所示。

2

7 武 汉 科 技 学 院 学 报 2000年

(2) 服务器 客户端

CS ocket S ockSrvr Cs ocket S ockClient ;

S ockSrvr.Create (nP ort )

S ockClient.Create (); S ockSrvr.Listen ()

S ockClient.C onnect (saddr ,nP ort ) CS ocket s ockRew , S ockSrvr.Accept (s ockrew ), Cs ocketFile file (&S ockClient ),

CS ockFile file (&s ockrew )

C Archive in (&file ,Carchive ::LOA

D ) C Archive in (&file ,Carchive ::LOAD ); C Archive out (&file ,Carchive ::ST OR

E ) C Archive out (&file ,Carchive ::ST ORE ); in >>dw Value , in >>dw Value ;

out <

图4 利用VC 在客户端和服务器之间建立套接字通信的流程

3.2 回调函数的使用

为了使网络通信更加方便,C AsyncS ocket 和CS ocket 提供了一些回调函数。主窗口通过调用这些回调函数来通知套接字的一些重要事件的来临。这些回调函数有OnReceive 、OnSend 、OnC onnect 、OnAccept 、OnClose ,它们可以通过在两个类中重载得到。这两个类仅仅是通过回调函数将消息转化为通知,具体的如何响应这些通知,还须我们自己来实现。

Void CReceS ocket ::OnReceive (int nErrorC ode )

 C ASyncS ocket ::OnReceive (nErrorC ode );

 Receive (1pBu f ,int nBu fLen ,int nFlags );

如果自己的类是C AsyncS ocket 继承而来,为了使通信更加便利,必须重载这些回调函数。如果自己的类是继承CS ocket ,将由你根据情况自己决定是否重载它们。必须指出的是,CS ocket 对象从不调用OnSend 和OnC onnect 这两个通知函数,而只能调用Send 函数来发送数据,直到发送完所有数据Send 才返回。同样只能调用C onnect 函数来进行连接,但调用C onnect 时会发生阻塞,直到成功地建立了连接或有错误发生。如果使用多线程,调用C onnect 的线程在C onnect ()发生阻塞时仍能处理Windows 消息。

3.3 利用多线程技术来开发网络通信

CS ockct 类的缺省方式为阻塞方式,为了避免阻塞的种种缺点,可以使用多线程技术。我们可以在一个工作线程中处理数据的接收和发送,该工作线程可以在后台运行,套接字在工作线程中的阻塞不会影响主线程中的其它活动,这样主线程可以处理主窗口的消息映射。除了使用工作线程外,我们还可以使用用户界面线程来实现;用户界面线程增加了消息映射,在下面的例子中将会用到。而以syncS ocket 类的缺省方式为非阻塞方式。在异步方式中,调用会立即返回,用G etLastError 函数会获相应的错误代码为WS AEW OU LDBLOCK,表示无连接可以接受。举例说明,在异步方式中,在调用Receive 函数后,会得到WS AEW OU LDBLOCK 的错误信息,直到OnReceive 回调函数被调用以通知我们可以再次接收数据了。

3.4 使用多线程进行套接字编程时应注意同步问题

37第4期 李红军 等: Windows S ockets 网络编程

47 武 汉 科 技 学 院 学 报 2000年

在使用多线程技术进行网络编程时,必须注意套接字对象的同步问题,可以使用线程同步机制来协调套接字对象的存取。对套接字调用时,如果不进行同步将可能会导致不可预测的结果。例如,如果有两个线程同时调用同一套接字进行send,那么数据发送的先后顺序就无法保证了。另外,如果两个线程中调用同一个套接字;在一个线程中关闭一个末完成的阻塞的套接字将会导致另一个线程使用同一套接字的阻塞调用出错(WS AEI NTER)返回,就象操作被取消一样。在Windows下,在两个线程中传递套接字对象是不安全的。对于套接字编程来说,一个套接字对象应该仅仅用于单个线程,在两个线程之间不能传递套接字对象。例如服务器一般可以接受多个连接,它每接受一个连接,就创建一个线程用来处理连接。为达到这个目的,仅仅在这两个线程个传递套接字对象是不够的。

虽然在两个线程之间不能传递套接字对象,但我们可以在线程之间传递线程句柄。因此我们可以按以下步骤进行:

(1)把附加在接受连接的线程的套接字对象上的套接字句柄分离出来。

(2)在两个线程中传递套接字句柄。

(3)在处理套接字连接的线程中,把这个套接字句柄附加到套接字对象上。

为了更好的说明以上方法,现将程序的部分列出:

//在主线程中创建监听线程的OnAccept函数

Void ClistenS ocket::OnAccept(int nErrorC ode)

{

C AsyncS ocket s oc://用于接受连接请求而建的临时对象

Accept(s oc)://接受请求

//创建新线程并挂起(该线程是用户界面线程)

CS ockThread3pThread=((CS ockThread3)A fx BeginThread(RUNTI MEC LASS(Cs ockThread), THRE AD PRI0RITY NORM A L、O,CRE ATE S USPE NDE D);

//将套接字句柄从套接字对象中分离出来,并保存

pThread一>m hS ocket=(S OCKET)s oc.Detach();

//开始执行新线程

pThread一>ResumeThread();

C AsyncS ocket::OnAccept(nErrorC ode);

}

//处理连接线程(即新线程)的1nitInstance函数,

BOO CS ockThread::1nitInstance()

{

//把这个套接字句柄附加到新的套接字对象上,

//这样主线程的通知函数就能发送到新线程中,在新线程中处理

m s ocket.Attach(m-hS ocket);

return TRUE:

}

通过以上步骤,我们就可以利用多线程技术来进行网络通信了。

4 结束语

在开发电子教室系统过程中,利用网络编程实现了教师机和学生机之间的连续图像的传输,传输效果相当令人满意。利用C AsyncS ocket 和CS ocket 两个类分别实现了网络通信。两个类实现的效果相差无几,由于CS ocket 类可以使用C Archive 对象之间传递数据,使用要方便些。如果能引入多线程技术进行网络通信以避免阻塞的话,那么CS ocket 将是很好的选择。C AsynS ocket 类使用更灵活,不过它需要对网络通信的细节和W ind ows 消息机制有更深入的了解。

参考文献

1 大卫?必立特(Dwid Bennelt )[美].Visual C ++5开发人员指南[M].北京:机械工业出版社.西蒙与舒斯特国际出版公司,1998.

2 张宝社,张宝峰.Windows 界面下的网络编程[M].合肥:中国科学技术大学出版社.1997.

3 曹 方,冯忠义.基于客户/服务器模式的S ocket 网络编程[J ].计算机工程.1998,25(2)

4 比尔?盖茨.Micros oft Visual studio 6.0MS DN Library (VC ++6.0part ).Micros oft 公司.1999.

5 比尔?盖茨.微软网站.http :∥w w w.Micros https://www.doczj.com/doc/821441408.html,/MS DN.Micros oft 公司.2000.

Windows Sockets N etw ork -programming

Li H ongjun Zhao Y ujiao Zhao Wei

Abstract :On the base of breif introduction on windows s ockets netw ork —programming ,this paper has given s ome exam ples on how to program and use the multithread on the netw ork by Visual C ++6.0;K ey w ords :netw ork ;s ockets ;block ;multithread

(上接第69页)

Several Discussion on Executive Stock Option

———Also on Corporate G overnance

Zuo K ai Mei Ning

Abstract The system of ES O has recceived com prehensive attention as a price -deternining mechanism of an enterprise ′s senior human capital.It is regarded as a way to s olve the problem of low -pay and low -incentive which has ham pered S OE for thinking years.the practice department has set about reforms from ES O.This paper puts questions on this view ,it thinks that one single system is not enough in im proving the structure of S OE ,the focuses for reforms in S OE should be on the selection of manager.K ey w ords :system of ES O ;corporate g overnance ;manager selection system

57第4期 李红军 等: Windows S ockets 网络编程

相关主题
文本预览
相关文档 最新文档