SOCKET编程原理.ppt

上传人:小飞机 文档编号:5448678 上传时间:2023-07-08 格式:PPT 页数:62 大小:359.50KB
返回 下载 相关 举报
SOCKET编程原理.ppt_第1页
第1页 / 共62页
SOCKET编程原理.ppt_第2页
第2页 / 共62页
SOCKET编程原理.ppt_第3页
第3页 / 共62页
SOCKET编程原理.ppt_第4页
第4页 / 共62页
SOCKET编程原理.ppt_第5页
第5页 / 共62页
点击查看更多>>
资源描述

《SOCKET编程原理.ppt》由会员分享,可在线阅读,更多相关《SOCKET编程原理.ppt(62页珍藏版)》请在三一办公上搜索。

1、SOCKET编程原理,内容,Socket简介Windows SocketLinux SocketSocket常用函数介绍TCP/IP网络程序框架与实例通信方式阻塞非阻塞,为什么需要Socket,普通的I/O操作过程打开文件读/写操作关闭文件TCP/IP协议被集成到操作系统的内核中,引入了新型的“I/O”操作进行网络操作的两个进程在不同的机器上,如何连接?网络协议具有多样性,如何进行统一的操作?需要一种通用的网络编程接口:Socket独立于具体协议BSD Socket(伯克利套接字)是通过标准的UNIX文件描述符和其它程序通讯的一个方法,目前已经被广泛移植到各个平台。,Socket类型,流式套接

2、字(SOCK_STREAM)提供了一个面向连接、可靠的数据传输服务,数据无差错、无重复的发送且按发送顺序接收。内设置流量控制,避免数据流淹没慢的接收方。数据被看作是字节流,无长度限制。数据报套接字(SOCK_DGRAM)提供无连接服务。数据包以独立数据包的形式被发送,不提供无差错保证,数据可能丢失或重复,顺序发送,可能乱序接收。,Socket的位置,两类系统中使用的Socket,不同操作系统中的SocketWindows Socket(Winsock)Linux Socket(BSD Socket),Windows Socket,简称Winsock,是在Windows环境下使用的一套网络编程规

3、范,基于4.3BSD的BSD Socket API制定1991年Winsock 1.1,16位,由WINSOCK.DLL支持,主要用在Windows 95中1997年Winsock 2.2 版,32位,由WSOCK32.DLL支持,主要用在Windows 98及以后的版本中已经成为Windows环境下网络编程的事实标准三类函数与BSD Socket相兼容的基本函数与BSD Socket相兼容的网络信息检索函数Windows专用扩展函数,Linux Socket,基本上就是BSD Socket需要使用的头文件数据类型:#include 函数定义:#include,TCP/IP网络程序框架,面向连

4、接的C/S程序工作流程无连接的C/S程序工作流程,面向连接的C/S程序工作流程(TCP),服务器端工作流程使用WSAStartup()函数检查系统协议栈安装情况使用socket()函数创建服务器端通信套接口使用bind()函数将创建的套接口与服务器地址绑定使用listen()函数使服务器套接口做好接收连接请求准备使用accept()接收来自客户端由connect()函数发出的连接请求根据连接请求建立连接后,使用send()函数发送数据,或者使用recv()函数接收数据使用closesocket()函数关闭套接口(可以先用shutdown()函数先关闭读写通道)最后调用WSACleanup()函

5、数结束Winsock Sockets API,面向连接的C/S程序工作流程(TCP),客户端程序工作流程使用WSAStartup()函数检查系统协议栈安装情况使用socket()函数创建客户端套接口使用connect()函数发出向服务器建立连接的请求(调用前可以不用bind()端口号,由系统自动完成)连接建立后使用send()函数发送数据,或使用recv()函数接收数据使用closesocet()函数关闭套接口最后调用WSACleanup()函数,结束Winsock Sockets API,面向连接的C/S程序工作流程(TCP),服务器与客户端五元组的建立,面向连接的C/S程序工作流程图(TC

6、P),无连接的C/S程序工作流程(UDP),无连接的数据报传输服务通信时,客户端与服务器端所使用的函数是类似的,其工作流程如下:使用WSAStartup()函数检查系统协议栈的安装情况使用socket()函数创建套接口,以确定协议类型调用bind()函数将创建的套接口与本地地址绑定,确定本地地址和本地端口号使用sendto()函数发送数据,或者使用recvfrom()函数接收数据使用closesocket()函数关闭套接口调用WSACleanup()函数,结束Windows Sockets API,无连接的C/S程序工作流程(UDP),注意事项:通信的一方可以不用bind()绑定地址和端口,由

7、系统分配不绑定IP地址和端口号的一方必须首先向绑定地址的一方发送数据无连接的应用程序也可以调用connect()函数,但是它并不向对方发出建立连接的请求,而是在本地返回,由内核将connect()中指定的目标IP地址和端口号记录下来,在以后的通信中就可以使用面向连接的数据发送函数send()和数据接收函数recv()无连接的数据报传输过程中,作为服务器的一方必须先启动无连接客户端一般不调用connect(),在数据发送前客户与服务器各自通过socket()和bind()建立了半相关,发送数据时除指定本地套接口的地址外,还需要指定接收方套接口地址,从而在数据收发过程中动态建立全连接,无连接的C/

8、S程序工作流程图(UDP),阻塞通信与非阻塞通信,阻塞方式:套接字进行I/O操作时,函数要等待到相关的操作完成以后才能返回,对提高处理机的利用率不利,但编程简单。非阻塞方式:套接字进行I/O操作时,无论操作成功与否,调用都会立即返回。阻塞方式编程简单,一个套接口的默认操作模式为阻塞,可以调用函数ioctlsocket()进行设置。,并发服务器,Socket常用函数介绍,基本函数网络信息检索函数,基本函数,网络连接函数socket创建套接字bind绑定本机端口connect建立连接listen监听端口accept接受连接recv,recvfrom数据接收send,sendto数据发送close,

9、shutdown关闭套接字,基本函数(续),转换函数IP地址转换函数inet_addr()点分十进制数表示的IP地址转换为网络字节序的IP地址inet_ntoa()网络字节序的IP地址转换为点分十进制数表示的IP地址字节排序函数htonl4字节主机字节序转换为网络字节序ntohl 4字节网络字节序转换为主机字节序htons2字节主机字节序转换为网络字节序ntohs2字节网络字节序转换为主机字节序,网络信息检索函数,网络信息检索函数gethostname获得主机名getpeername获得与套接口相连的远程协议地址getsockname获得套接口本地协议地址gethostbyname根据主机名取

10、得主机信息gethostbyaddr根据主机地址取得主机信息getprotobyname根据协议名取得主机协议信息getprotobynumber根据协议号取得主机协议信息getservbyname根据服务名取得相关服务信息getservbyport根据端口号取得相关服务信息getsockopt/setsockopt获取/设置一个套接口选项 ioctlsocket设置套接口的工作方式,Windows中的Socket编程,Windows中的Socket编程Winsock 的启动Winsock API基本函数TCP/IP网络程序框架(C/S模式)阻塞与非阻塞通信方式实例程序说明,Winsock,W

11、insock是一个基于Socket模型的API,在Windows系统中广泛使用需要包含头文件Winsock2.h,需要使用库ws2_32.lib,包含办法可以用语句来告诉编译时调用该库#pragma comment(lib,”ws2_32.lib”);如果使用Visual C+6.0,可以通过“工程”“设置”“工程设置”“链接”“对象/库模块”中加入“ws2_32.lib”,Windows Socket的启动,使用Winsock API编制的网络应用程序中,在调用任何一个Winsock函数之前都必须检查协议栈安装情况,使用函数WSAStartup()完成操作。int WSAStartup(WO

12、RD wVersionRequested,LPWSADATA lpWSAData);wVersionRequested是一个WORD型(双字节型)数值,指定使用的版本号,对Winsock2.2而言,此参数的值为0 x0202,也可以用宏MAKEWORD(2,2)来获得lpWSAData是一个指向WSADATA结构的指针,它返回关于Winsock实现的详细信息,Winsock启动示例,#include WORD wVersionRequested;WSADATA wsaData;wVersionRequested=MAKEWORD(2,2);if(WSAStartup(wVersionReque

13、sted,/说明WinsockDLL正确加载,可以执行以下代码,基本函数,网络连接函数socket创建套接字bind绑定本机端口connect建立连接listen监听端口accept接受连接recv,recvfrom数据接收send,sendto数据发送close,shutdown关闭套接字,创建套接口socket(),应用程序在使用套接口通信前,必须要拥有一个套接口,使用socket()函数来给应用程序创建一个套接口。SOCKET socket(int af,int type,int protocol);,socket()参数说明,af参数说明套接字接口要使用的协议地址族,地址族与协议族含义

14、相同。如果想建立一个TCP或UDP,只能用常量AF_INET表示使用互联网协议(IP)地址。Winsock还支持其他协议,但一般很少使用。type参数描述套接口的类型,af是AF_INET的时候只能为SOCK_STREAM、SOCK_DGRAM或SOCK_RAWprotocol说明该套接口使用的特定协议,当协议地址族af和协议类型type确定后,协议字段可以使用的值是限定的,基本函数,网络连接函数socket创建套接字bind绑定本机端口connect建立连接listen监听端口accept接受连接recv,recvfrom数据接收send,sendto数据发送close,shutdown关闭

15、套接字,指定本地地址bind(),当socket()创建了一个套接口后,需要将该套接口与该主机上提供服务的某端口联系在一起,bind()函数用于完成这样的绑定。int bind(SOCKET s,const struct sockaddr FAR*name,int namelen);,bind()参数说明,s标识一个未绑定的套接口描述字,它是socket()函数调用成功时返回的值name是一个与指定协议有关的地址结构指针,存储了套接口的地址信息,Winsock中使用sockaddr_in结构指定IP地址和端口信息struct sockaddr_inshort sin_family;u_shor

16、t sin_port;struct in_addrsin_addr;charsin_zero8;sin_family一般为AF_INET,表示使用网络字节序的IP地址族;sin_port是以网络字节序表示的16位端口号;sin_addr是32位IP地址;sin_zero字段一般不用,用0填充 IP地址参数为INADDR_ANY,则由系统内核来自动指定 port为0,则由系统自动指派一个10245000之间惟一的端口号namelen表示地址参数(name)的长度,bind()实例,#include SOCKET s;sockaddr_in tcpaddr;int iSockErr;int por

17、t=5000;/端口号s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);tcpaddr.sin_family=AF_INET;tcpaddr.sin_port=htons(port);tcpaddr.sin_addr.s_addr=htonl(INADDR_ANY);if(bind(s,(LPSOCKADDR)函数调用成功,进行其他处理。,基本函数,网络连接函数socket创建套接字bind绑定本机端口connect建立连接listen监听端口accept接受连接recv,recvfrom数据接收send,sendto数据发送close,shutdown关闭套

18、接字,服务器端启动监听listen()函数,在一个服务器端用socket()调用成功创建了一个套接口,并用bind()函数和一个指定的地址关联后,就需要指示该套接口进入监听连接请求状态,这需要通过listen()函数来实现int listen(SOCKET s,int backlog);s代表一个已绑定了地址,但还未建立连接的套接口描述字backlog指定了正在等待连接的最大队列长度,基本函数,网络连接函数socket创建套接字bind绑定本机端口connect建立连接listen监听端口accept接受连接recv,recvfrom数据接收send,sendto数据发送close,shutd

19、own关闭套接字,客户端请求连接connect()函数,当服务器端建立好套接口并与一个本地地址绑定后,就进入监听状态,等待客户发出连接请求。在客户端套接口建立好之后,就调用connect()函数来与服务器建立连接。int connect(SOCKET s,const struct sockaddr FAR*name,int namelen);,connect()函数参数说明,s将要建立连接的套接口描述字name是一个指向远端套接口地址结构(sockaddr_in)的指针,表示s套接口欲与其建立一条连接namelen是服务器端的地址长度,即name的长度,Connect()函数的说明,在客户端使

20、用该函数请求建立连接时,将激活建立连接的三次握手,用来建立一条到服务器TCP的连接。如果调用该函数前没有调用bind()来绑定本地地址,则由系统隐式绑定一个地址到该套接口该函数用在UDP的客户端时,connect()函数并不是真正地发出建立请求连接的请求,调用将从本地操作系统直接返回。这样可以将服务器的地址信息保存下来,在后续UDP端口发送数据时,由套接口自动在发送函数中填入服务器地址,而不需要由应用程序在调用发送函数时填入,基本函数,网络连接函数socket创建套接字bind绑定本机端口connect建立连接listen监听端口accept接受连接recv,recvfrom数据接收send,

21、sendto数据发送close,shutdown关闭套接字,服务器端接受连接accept()函数,在服务器端通过listen()函数调用表示服务器进入监听客户的连接请求状态,而在服务器端调用accept()函数时表示可以接收来自客户端由connect()发出的连接请求,双方进入连接状态。SOCKET accept(SOCKET s,struct sockaddr FAR*addr,int FAR*addrlen);,accept()函数参数说明,s标识一个套接字,该套接口处于监听状态addr是一个地址结构的指针,用来存放发出连接请求的那个客户机的IP地址信息addrlen指出客户套接口地址结构

22、的长度函数说明:该函数用于面向连接的服务器端,在IP协议族中,只用于TCP服务器端,基本函数,网络连接函数socket创建套接字bind绑定本机端口connect建立连接listen监听端口accept接受连接recv,recvfrom数据接收send,sendto数据发送close,shutdown关闭套接字,发送数据-send()函数,在已经建立连接的套接口上发送数据,可以使用send()函数int send(SOCKET s,const char FAR*buf,int len,int flags);,send()函数参数说明,s用于标识已建立连接的套接字buf是一个字符缓冲区,内有将要

23、发送的数据len即将发送的缓冲区中的字符数flags用于控制数据传输方式,0表示按正常方式发送数据;宏MSG_DONTROUTE说明系统目标主机就在直接连接的本地网络中,无需路由选择;MSG_OOB指出数据是按带外数据发送的,如urgency函数说明:send()函数适用于已建立连接的数据报或流式套接口发送数据,对于数据报类型必须注意发送数据长度不大于通信子网的IP包最大长度,基本函数,网络连接函数socket创建套接字bind绑定本机端口connect建立连接listen监听端口accept接受连接recv,recvfrom数据接收send,sendto数据发送close,shutdown关

24、闭套接字,接收数据recv()函数,对于已建立连接的套接口来说,要从套接口上接收数据,就要使用recv()函数。int recv(SOCKET s,char FAR*buf,int len,int flags);,recv()函数参数说明,s为已建立连接的套接口buf为用于接收数据的缓冲区len为缓冲区的长度flags指定调用的方式。0表示接收的是正常数据,无特殊行为。MSG_PEEK表示会使有用的数据复制到所提供的接收端缓冲区内,但是没有从系统缓冲区中将数据删除。MSG_OOB表示处理带外数据。,无连接的套接口上接收数据-recvfrom(),对于无连接的套接口来说,要从套接口上接收一个数据

25、报并保存发送数据的源地址,就要使用recvfrom()函数。int recvfrom(SOCKET s,char FAR*buf,int len,int flags,struct sockaddr FAR*from,int FAR*fromlen);,recvfrom()函数参数说明,s标识一个套接口的描述字buf接收数据的缓冲区len接收数据缓冲区的长度flags调用操作方式,同recv()中的flagsfrom可选指针,指向装有源地址的缓冲区fromlen可选指针,指向from缓冲区的长度值函数说明:该函数的用法与有连接时recv()的用法一致,也可以用于有连接时数据的接收,在无连接套接口

26、上发送数据-sendto(),对于无连接的套接口来说,要从套接口上发送一个数据报,就要使用sendto()函数int sendto(SOCKET s,const char FAR*buf,int len,int flags,const struct sockaddr FAR*to,int tolen);,sendto()函数参数说明,s本机的套接字buf待发送数据的缓冲区len指明buf缓冲区中要发送的数据长度flags调用方式标志位,同send()中的flagsto可选指针,指向接收数据的目的套接口地址tolen是to所指的地址的长度函数说明:该函数的使用方法类似send()函数,当用于无连

27、接套接字接口,调用函数前要设置,指出目标IP地址和目标端口号。如果用于有连接的套接口时,则不能指定目标地址和目标端口,将to设置为空,地址长度设为0。,基本函数,网络连接函数socket创建套接字bind绑定本机端口connect建立连接listen监听端口accept接受连接recv,recvfrom数据接收send,sendto数据发送close,shutdown关闭套接字,关闭读写通道-shutdown()函数,在一个套接口上的读写操作完成后,应该首先使用shutdown()函数来关闭套接口的读通道、写通道或读写通道,这样做的好处是当双方不再有数据要发送或接收时,可以通知对方,以防止数据

28、丢失,并能“优雅”地关闭连接int shutdown(SOCKET s,int how);,shutdown()函数参数说明,s标识一个套接口的描述字how是一个标志,用于描述禁止哪些操作,取值如下表所示,关闭套接口-closesocket()函数,shutdown函数只关闭读写通道,并不关闭套接口,且套接口所占有的资源将被一直保留到closesocket()调用之前。一个套接口不再使用时一定要关闭这个套接口,以释放与该套接口关联的所有资源,包括等候处理的数据。int closesocket(SOCKET s);参数s表示即将被关闭的套接口,基本函数(续),转换函数IP地址转换函数inet_a

29、ddr()点分十进制数表示的IP地址转换为网络字节序的IP地址inet_ntoa()网络字节序的IP地址转换为点分十进制数表示的IP地址字节排序函数htonl4字节主机字节序转换为网络字节序ntohl 4字节网络字节序转换为主机字节序htons2字节主机字节序转换为网络字节序ntohs2字节网络字节序转换为主机字节序,IP地址转换函数,char*inet_ntoa(struct in_addr in)in为传入参数,表示一个结构型的IP主机地址,该函数将一个32位数字表示的IP地址转换成点分十进制IP地址字符串unsigned long inet_addr(const char FAR*cp)

30、该函数将一个点分十进制IP地址字符串转换成32位数字表示的IP地址。两函数互为反函数,字节序转换函数,u_long htonl(u_long hostlong)4字节主机字节序表示的整数转换为4字节相应的网络字节序表示的整数u_short htons(u_short hostshort)2字节主机字节序表示的整数转换为2字节相应的网络字节序表示的整数u_long ntohl(u_long netlong)4字节网络字节序表示的整数转换为4字节相应的主机字节序表示的整数u_short ntohs(u_short netshort)2字节网络字节序表示的整数转换为2字节相应的主机字节序表示的整数,

31、终止使用Winsock-WSACleanup()函数,当应用程序不再使用Winsock API中的任何函数时,必须调用WSACleanup()将其从Windows Socket的实现中注销,以释放为此应用程序或DLL分配的任何资源。int WSACleanup(void);函数说明:WSACleanup()函数是任何一个Winsock应用程序在最后必须要调用的函数。在一个多线程的环境下,WSACleanup()函数中止了Windows Sockets在所有线程上的操作,高级网络编程API,MFC编程技术定义了用于网络编程的Winsock类,类名为CAsyncSocket;还定义了一个派生于CAsyncSocket的CSocket类。这两个类简单实用,用户可以使用它们来实现自己的网络程序。与前面的介绍相似,使用MFC的Winsock类进行操作时需要使用Winsock2.h、Winsock32.dll和ws2_32.lib三个文件,The End,

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号