ImageVerifierCode 换一换
格式:PPTX , 页数:105 ,大小:3.52MB ,
资源ID:18071493      下载积分:10 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bingdoc.com/d-18071493.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(VisualC网络编程案例实战之Socket套接字编程.pptx)为本站会员(wj)主动上传,冰点文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰点文库(发送邮件至service@bingdoc.com或直接QQ联系客服),我们立即给予删除!

VisualC网络编程案例实战之Socket套接字编程.pptx

1、第2章 Socket套接字编程,套接字是由美国伯克利大学提出并设计的一种在网络中不同主机之间进行数据交换的通信桥梁。在实际生活中,人们所使用的网络通信软件功能均是基于Socket套接字作为通信桥梁实现。所以,套接字在网络编程中,有着非常重要的作用。本章将向用户介绍使用Socket套接字编程的相关概念以及实现方法。,2.1 寻址方式和字节顺序,在讲解套接字编程前,用户需要首先了解一下什么是寻址方式和字节顺序。在Socket套接字编程中,为了准确定位通信双方和数据传输的有效性、完整性,编程时必须使用统一的寻址方式和字节排列顺序。,2.1.1 寻址方式,因为套接字需要在各种网络协议中使用,所以为了区

2、分程序所使用的网络协议必须使用统一的寻址方式。例如,在TCP/IP协议通信中,用户使用IP地址和端口号进行确定通信双方。而在其他的协议中不一定也使用该方式确定通信双方。在Winsock(Socket API)中,用户可以使用TCP/IP地址家族中统一的套接字地址结构解决TCP/IP寻址中可能出现的问题。,该套接字地址结构定义如下:struct sockaddr_in short sin_family;/指定地址家族即地址格式 unsigned short sin_port;/端口号码 struct in_addr sin_addr;/IP地址 char sin_zero8;/需要指定为0;,在

3、这个结构中,成员sin_family指定使用该套接字地址的地址家族。在这里必须设置为AF_INET,表示程序所使用的地址家族是TCP/IP。注意:该结构的最后一个成员并未实际使用,主要是为了与第一个版本的套接字地址结构大小相同而设置。在实际使用时,将这8个字节直接设为0即可。,该结构成员变量sin_addr表示32位的IP地址结构。其结构定义如下:struct in_addr union struct unsigned char s_b1,s_b2,s_b3,s_b4;S_un_b;/用4个u_char字符描述IP地址 struct unsigned short s_w1,s_w2;S_un_

4、w;/用2个u_short类型描述IP地址 unsigned long S_addr;/用1个u_long类型描述IP地址 S_un;,通常,用户在网络编程中使用1个u_long类型的字符进行描述IP地址即可。例如,使用IP地址结构in_addr 进行描述IP地址“218.6.132.5”。代码如下:sockaddr_in addr;addr.sin_addr.S_un.S_addr=inet_addr(218.6.132.5);在程序中,首先定义sockaddr_in结构对象addr,然后为IP地址结构in_addr中的成员S_addr赋值。因为结构成员S_addr所描述的IP地址均为网络字

5、节顺序,所以程序调用inet_addr()函数将字符串IP转换为以网络字节顺序排列的IP地址。,2.1.2 字节顺序,在Socket套接字编程中,传输数据的排列顺序以网络字节顺序和主机字节顺序为主。通常情况下,如果用户将数据通过网络发送时,需要将数据转换成以网络字节顺序排列,否则可能造成数据损坏。如果用户是将网络中接收到的数据存储在本地计算机上,那么需要将数据转换成以主机字节顺序排列。从数据存储的角度来讲,网络字节顺序即将数据中最重要的字节首先进行存储,而主机字节顺序则将不重要的字节首先存储。注意:IP地址结构in_addr中的成员S_addr的值均是以网络字节顺序排列。,1字节顺序转换函数,

6、在Winsock中提供了几个关于网络字节顺序与主机字节顺序之间的转换函数。函数定义如下:/将一个u_short类型的IP地址从主机字节顺序转换到网络字节顺序u_short htons(u_short hostshort);/将一个u_long类型的IP地址从主机字节顺序转换到网络字节顺序u_long htonl(u_long hostlong);/将一个u_long类型的IP地址从网络字节顺序转换到主机字节顺序u_long ntohl(u_long netlong);/将一个u_short类型的IP地址从网络字节顺序转换到主机字节顺序u_short ntohs(u_short netshort

7、);/将一个字符串IP转换到以网络字节顺序排列的IP地址unsigned long inet_addr(const char FAR*cp);/将一个以网络字节顺序排列的IP地址转换为一个字符串IPchar FAR*inet_ntoa(struct in_addr in);以上函数的使用均与操作系统平台无关。因此,用户使用这些函数编写的程序能在所有操作系统平台中运行。,2实例程序,在本节中,将编写实例程序向用户讲解字节顺序转换函数的用法。代码如下:./省略部分代码sockaddr_in addr;/定义套接字地址结构变量addr.sin_family=AF_INET;/指定地址家族为TCP/I

8、Paddr.sin_port=htons(80);/指定端口号/将字符串IP转换为网络字节顺序排列的IPaddr.sin_addr.S_un.S_addr=inet_addr(127.0.0.1);/将网络字节顺序排列的IP转换为字符串IPchar addres=inet_ntoa(addr.sin_addr.S_un.S_addr);,在程序中,用户首先使用函数inet_addr()将字符串IP“127.0.0.1”转换为以网络字节顺序排列的IP并保存在IP地址结构成员S_addr中。然后,再使用函数inet_ntoa()则将该成员所表示的IP值转换成字符串IP。,2.1.3 Socket相

9、关函数,由于Windows网络程序开发均是基于Windows套接字实现,所以本节将重点介绍MFC中的CSocket类以及使用CSocket类编程的基本流程。,1创建套接字,使用CSocket类创建套接字对象是通过该类的构造函数创建的。其原型如下:CSocket:CSocket();例如,用户创建CSocket类对象,代码如下:CSocket sock;如果用户需要创建套接字对象指针,则应该使用关键字new进行创建。代码如下:CSocket*sock;/定义套接字指针对象sock=new CSocket;/使用new关键字创建套接字,2绑定地址信息,如果用户创建服务器套接字,那么用户应该调用该类

10、的函数Bind()将套接字对象与服务器地址信息绑定在一起。其原型如下:BOOL Bind(const SOCKADDR*lpSockAddr,int nSockAddrLen);该函数的作用是将套接字对象与服务器地址结构绑定在一起。如果函数调用成功,则返回true。否则,返回false。参数lpSockAddr指定将要绑定的服务器地址结构,参数nSockAddrLen表示地址结构的长度。,例如,用户将上面创建的套接字对象与地址结构绑定。代码如下:CSocket sock;/创建套接字对象sockaddr_in addr;/定义套接字地址结构变量addr.sin_family=AF_INET;/

11、指定地址家族为TCP/IPaddr.sin_port=htons(80);/指定端口号/将字符串IP转换为网络字节顺序排列的IPaddr.sin_addr.S_un.S_addr=inet_addr(127.0.0.1);sock.Bind(SOCKADDR*)addr,sizeof(addr);/绑定套接字与地址结构./省略部分代码,在服务器端,当地址信息绑定套接字成功后,还需要调用函数Listen()在指定端口监听客户端的连接请求。函数Listen()的原型如下:BOOL Listen(int nConnectionBacklog=5);参数nConnectionBacklog表示套接字监

12、听客户端请求的最大数目。该参数的有效范围是15。默认为5,表示该套接字只能监听5个客户端所发送的连接请求。,例如,套接字监听5个客户端的连接请求,代码如下:CSocket sock;/创建套接字对象sockaddr_in addr;/定义套接字地址结构变量addr.sin_family=AF_INET;/指定地址家族为TCP/IPaddr.sin_port=htons(80);/指定端口号/将字符串IP转换为网络字节顺序排列的IPaddr.sin_addr.S_un.S_addr=inet_addr(127.0.0.1);sock.Bind(SOCKADDR*)addr,sizeof(addr

13、);/绑定套接字与地址结构sock.Listen(5);/监听端口,3连接服务器,客户端创建套接字成功以后,可以调用函数Connect()向服务器发送连接请求。函数原型如下:BOOL Connect(const SOCKADDR*lpSockAddr,int nSockAddrLen);该函数调用成功,则返回true。否则,将返回false。参数lpSockAddr表示将连接的服务器地址结构。参数nSockAddrLen表示地址结构的长度大小。,例如,服务器IP地址为“127.0.0.1”,端口为80,客户端连接服务器,代码如下:CSocket sock;/创建套接字对象sockaddr_in

14、 addr;/定义套接字地址结构变量addr.sin_family=AF_INET;/指定地址家族为TCP/IPaddr.sin_port=htons(80);/指定端口号/将字符串IP转换为网络字节顺序排列的IPaddr.sin_addr.S_un.S_addr=inet_addr(127.0.0.1);sock.Connect(SOCKADDR*)addr,sizeof(addr);/连接服务器,4数据交换,无论是服务器,还是客户端都是通过函数Send()和Receive()进行数据交换。函数原型如下:virtual int Send(const void*lpBuf,int nBufLe

15、n,int nFlags=0);virtual int Receive(void*lpBuf,int nBufLen,int nFlags=0);其中,函数Send()用于发送指定缓冲区的数据,函数Receive()用于接收对方发送的数据,并将数据存放在指定缓冲区中。参数lpBuf表示数据缓冲区地址。参数nBufLen表示数据缓冲区的大小。参数nFlags表示数据发送或接收的标志,一般情况下,该参数均设置为0。,例如,使用这两个函数进行数据的发送和接收。代码如下:./省略部分代码char buff=a;/定义并初始化数据缓冲区sock.Send(/接收数据并将数据存放在数据缓冲区中,5关闭套接

16、字对象,当服务器和客户端的通信完成以后,用户还必须调用函数Close()将套接字对象关闭。否则,程序可能在退出时发生错误。该函数原型如下:virtual void Close();例如,客户端关闭套接字对象,代码如下:./省略部分代码sock.Close();/关闭套接字对象套接字关闭的同时,也将服务器与客户端之间连接关闭了。,本节主要向用户介绍了CSocket类的常用函数以及用法。当用户创建VC应用程序时,如果没有为应用程序指定支持Windows Socket,那么用户必须手动添加该类的头文件afxsock.h。否则,程序将不能使用CSocket类。,2.2 Winsock网络程序开发流程,

17、本节将向用户讲述基于Windows Socket的应用程序开发步骤,并将编写实例程序向用户介绍网络应用程序的开发过程以及CSocket类的具体使用方法。本节中的实例程序均在VC中进行编写、调试。,2.2.1 VC中创建工程的步骤,用户在VC中使用应用程序向导创建基于套接字的应用程序工程时,必须为该应用程序指定支持Windows Socket功能。否则,创建的应用程序不能进行网络通信。如果用户创建工程项目成功,则在应用程序向导设置的第二步,将询问用户是否需要在项目中支持Windows Socket功能,如图2.1所示。,图2.1 支持Windows Socket功能,如果用户在应用程序的第二步没

18、有选择项目支持Windows Socket功能,则在程序中手动添加代码也可以达到同样的目的。其代码如下:#include/包含CSocket类的头文件注意:头文件afxsock.h中包含了CSocket类的变量以及函数定义。,2.2.2 Winsock编程流程,在本书的第1章中,已经向用户介绍了Winsock函数是用于网络编程的Windows API函数。本章在前一节中,向用户介绍了CSocket类的基本编程流程。所以,在本节中将向用户介绍使用Socket API函数进行网络程序开发的基本流程与方法。,1初始化和释放套接字库,由于所有的Winsock函数均是从动态链接库WS2_32.DLL中导

19、出的,但是,VC在默认情况下并没有与该库进行连接。所以,用户需要在VC中进行相关设置,使其连接动态库WS2_32.DLL。添加方法是选择“Project”|“Settings”命令,将弹出Project Settings对话框,如图2.2所示。,图2.2 添加动态链接库,用户在工程设置对话中,可以修改或添加库模块(如图2.2所示)。在库模块中添加动态链接库WS2_32.DLL。这样,程序就可以调用Winsock函数了。,用户必须首先从动态链接库中调用函数WSAStartup()对该库进行初始化,之后才能从该库中继续正确调用其他Winsock函数。否则,将出现错误。函数WSAStartup()的

20、原型如下:int WSAStartup(WORD wVersionRequested,LPWSADATA lpWSAData);该函数调用成功,将返回0。否则,调用函数失败。参数wVersionRequested表示当前套接字库的版本号。例如,当前套接字版本号为2.0,则将该参数设置为2.0。代码如下:WORD wVersionRequested=MAKEWORD(2,0);,参数lpWSAData指向结构体WSADATA的指针变量,表示获取到的套接字库详细信息。该结构体定义如下:typedef struct WSAData WORD wVersion;/库文件建议应用程序使用的版本号 WOR

21、D wHighVersion;/库文件支持的最高版本 char szDescriptionWSADESCRIPTION_LEN+1;/描述库文件的字符串 char szSystemStatusWSASYS_STATUS_LEN+1;/系统状态字符串 unsigned short iMaxSockets;/同时支持的最大套接字数 unsigned short iMaxUdpDg;/已废弃 char FAR*lpVendorInfo;/已废弃 WSADATA,FAR*LPWSADATA;,用户初始化套接字库,代码如下:WSAData data;/定义WSAData变量WORD wVersionRe

22、quested=MAKEWORD(2,0);/定义套接字库版本号:WSAStartup(wVersionRequested,2创建套接字句柄,在Socket API中,创建套接字句柄的函数是socket()。该函数原型如下:SOCKET socket(int af,/指定套接字所使用的地址格式,在本章中只能设置为AF_INET int type,/套接字类型 int protocol/如果参数type已经指定套接字类型为TCP或UDP,则该参数可以设置为0);该函数执行成功,将返回新创建的套接字句柄。否则,将返回INVALID_SOCKET表示失败。参数type的取值如表2.1所示。,表2.1

23、 套接字类型取值,例如,创建流式套接字的句柄。代码如下:SOCKET s;/定义套接字句柄s=:socket(AF_INET,SOCK_STREAM,0);/创建并返回套接字句柄,3绑定地址信息,对于服务器而言,套接字创建成功后,还应该将套接字与地址结构信息相关联。实现这一功能的函数是bind()。该函数原型如下:int bind(SOCKET s,/套接字句柄 const struct sockaddr FAR*name,/地址结构信息 int namelen/地址结构的大小);该函数调用成功,则返回0。否则,函数调用失败。,例如,将套接字句柄绑定到本地地址,代码如下:./省略部分代码soc

24、kaddr_in addr;/定义套接字地址结构变量addr.sin_family=AF_INET;/指定地址家族为TCP/IPaddr.sin_port=htons(80);/指定端口号addr.sin_addr.S_un.S_addr=INADDR_ANY/表示服务器能够接收任何计算机发来的请求:bind(s,(sockaddr)/绑定套接字到指定地址结构,当服务器程序将套接字句柄绑定套接字地址成功时,则调用函数listen()实现监听端口的功能。该函数原型如下:int listen(SOCKET s,/实现监听功能的套接字句柄 int backlog/指定监听的最大连接数量);该函数仅被

25、用于流式套接字上。如果多个客户端同时向服务器发出连接请求,并且已超过了最大监听数,则客户端将返回错误代码。,例如,程序在已创建的套接字s上进行监听,代码如下:./省略部分代码:listen(s,5);/在套接字上进行监听,并且将最大监听数指定为5,4连接,客户端程序连接服务器使用函数connect()实现。函数原型如下:int connect(SOCKET s,/套接字句柄 const struct sockaddr FAR*name,/将要连接的服务器地址信息结构指针 int namelen/地址信息结构体长度);,例如,客户端使用该函数连接地址为“127.0.0.1”,端口为80的服务器。

26、代码如下:sockaddr_in addr;/定义套接字地址结构变量addr.sin_family=AF_INET;/指定地址家族为TCP/IPaddr.sin_port=htons(80);/指定端口号addr.sin_addr.S_un.S_addr=inet_addr(127.0.0.1);/指定服务器地址SOCKET s;/定义套接字句柄s=:socket(AF_INET,SOCK_STREAM,0);/创建并返回套接字句柄:connect(s,(sockaddr)/连接服务器.,如果服务器接收到客户端的连接请求,则可以调用函数accept()接受该请求。函数原型如下:SOCKET a

27、ccept(SOCKET s,/套接字句柄 struct sockaddr FAR*addr,/获取连接对方的地址信息 int FAR*addrlen/地址长度);该函数如果调用成功,则返回一个新的套接字句柄,用于通信双方数据的传输。,5数据收发,当用户使用Winsock编程时,都是调用函数send()和recv()进行数据的发送和接收。函数原型如下:/发送数据函数int send(SOCKET s,const char FAR*buf,int len,int flags);/接收数据函数int recv(SOCKET s,char FAR*buf,int len,int flags);,两个

28、函数的各个参数表示的意义均相同。参数buf是指向数据缓冲区的指针变量,参数flags通常设置为0。注意:如果服务器使用上面的函数进行数据收发,则参数s应该为监听函数返回的新套接字句柄。如果客户端使用以上函数进行数据收发,则参数s应该为客户端创建的套接字句柄。,6关闭套接字,当套接字使用完毕或程序退出时,用户应该调用函数closesocket()关闭套接字句柄。函数原型如下:int closesocket(SOCKET s/将关闭的套接字句柄);参数s表示即将关闭的套接字句柄。例如,用户关闭前面创建的套接字句柄s,代码如下::closesocket(s);本节主要向用户讲述了使用Winsock函

29、数进行程序设计的基本流程,并讲解了部分常用函数的用法等知识。希望用户在实际编程的过程中,能不断地对本节知识进行回顾,加深理解。,2.2.3 基于TCP的Sockets编程,在本节中,将编写一个简单的TCP服务器和TCP客户端程序。这两个实例程序均为控制台程序窗口。,1TCP服务器,首先,在VC中新建一个基于控制台的应用程序工程,并将该工程命名为“TCP服务器”,如图2.3所示。,图2.3 新建控制台应用程序,然后,单击“OK”按钮进行应用程序类型的设置。在本节中,将新建的控制台程序类型指定为一个空工程,如图2.4所示。,图2.4 设置空的控制台程序,用户还需要在VC中添加一个空白的C+源文件,

30、名称为TCPSEVER,如图2.5所示。,图2.5 新建C+资源文件,用户在新建的C+源文件中进行代码编写。代码如下:编译并运行程序,如图2.6所示。,图2.6 服务器启动界面,服务器程序启动以后,如果没有客户端向其发送连接请求,则服务器将一直等待直到有客户端程序连接。,2TCP客户端,在VC中创建基于控制台的应用程序,命名为“TCP客户端”。其方法与TCP服务器的创建过程相同。所以,在这里不再赘述,请读者复习前面的相关内容。在新建的C+源文件TCPClient中,用户可以编写客户端的功能代码。代码如下:编译并运行程序,如图2.7所示。,图2.7 客户端启动界面,如果用户首先打开服务器程序,再

31、打开客户端程序,则服务器会接受客户端的连接请求,而客户端会显示服务器发送的欢迎信息,如图2.8所示。,图2.8 打开服务器与客户端,本节向用户讲解了TCP服务器与客户端的通信过程,并编写了实例代码。用户在学习的过程中,如果对本章实例有兴趣,可以将随书光盘中的相应的实例代码进行改写,以达到自己的要求。,2.2.4 基于UDP的Sockets编程,基于UDP的网络程序是面向无连接,不可靠的一种应用程序。所以,当程序创建套接字句柄成功以后,便可以直接调用函数进行数据收发,最后,关闭套接字对象。在整个过程中,程序都不用调用任何函数连接服务器或者接受客户端的连接等操作。这种类型的应用程序多用在即时通信中

32、。,在UDP中进行数据收发的函数是sendto()和recvfrom()。函数原型如下:int sendto(/发送函数 SOCKET s,/套接字句柄 const char FAR*buf,/数据缓冲区 int len,/数据的长度 int flags,/一般设置为0 const struct sockaddr FAR*to,/目标地址结构信息 int tolen/目标地址结构大小);int recvfrom(SOCKET s,char FAR*buf,int len,int flags,struct sockaddr FAR*from,int FAR*fromlen);/接收函数,函数re

33、cvfrom()的各个参数与函数sendto()的参数基本一致。参数from是指向地址结构sockaddr_in的指针,表示数据发送方的地址信息。参数fromlen表示该地址结构的大小。,1UDP服务器,首先,在VC中创建基于控制台程序窗口的应用程序,并命名为“UDP服务器”,如图2.9所示。,图2.9 新建UDP服务器,然后,将该工程类型同样指定为空工程。在新建的工程中新建一个C+源文件,名称为UDPSever,如图2.10所示。,图2.10 新建C+源文件,现在用户可以在该源文件中编写UDP服务器的代码。代码如下:编译并运行程序,如图2.11所示。,图2.11 UDP服务器启动界面,2UDP客户端,在VC中创建UDP客户端程序时,与UDP服务器相同,工程类型均为空工程。所以,用户只需在C+源文件中编写代码实现UDP客户端。代码如下:编译并运行程序,如图2.12所示。,图2.12 客户端

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2