Socket通信(PPT36页)

上传人:gp****x 文档编号:243122775 上传时间:2024-09-16 格式:PPT 页数:36 大小:282KB
返回 下载 相关 举报
Socket通信(PPT36页)_第1页
第1页 / 共36页
Socket通信(PPT36页)_第2页
第2页 / 共36页
Socket通信(PPT36页)_第3页
第3页 / 共36页
点击查看更多>>
资源描述
单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,*,单击此处编辑母版标题样式,Socket,1,Socket,通信,(,一),Socket,相关理论,(二),TCP,的工作流程,(三),Socket,相关代码,2,(一),Socket,相关理论,提到网络编程就必须说,Socket,。因写网络程序就必须要用,Socket,。,对于网络编程,我们也言必称,TCP/IP,,似乎其它网络协议已经不存在了。对于,TCP/IP,,我们还知道,TCP,和,UDP,,,TCP,面向连接,,,UDP,面向无连接,,前者可以保证数据的正确和可靠性,后者则允许数据丢失。,最后,我们还知道,在建立连接前,必须知道对方的,IP,地址和端口号,。,3,(一),Socket,相关理论,我们还知道如下几个事实:,1,。一个指定的,端口号,不能被多个程序共用。,比如,如果,鼠标,占用了,80,端口,那么,U,盘,就不能用,80,端口了。,2,。很多,防火墙,只允许特定目标端口的数据包通过。,3,。服务程序在,listen,某个端口并,accept,某个连接请求后,会生成一个,新的,socket,来对该请求进行处理。,4,(一),Socket,相关理论,如果一个,socket,创建后并与,80,端口绑定后,是否就意味着该,socket,占用了,80,端口呢?如果是这样的,那么当其,accept,一个请求后,生成的新的,socket,到底使用的是什么端口呢,?如果是系统,会默认给其分配一个空闲的端口号,,,那一定不是,80,端口了,于是以后的,TCP,数据包的目标端口就不是,80,了,-,防火墙一定会阻止其通过的!,5,(一),Socket,相关理论,实际上,我们可以看到,防火墙并没有阻止这样的连接,而且这是最常见的连接请求和处理方式。,为什么防火墙没有阻止这样的连接?,它是如何判定那条连接是因为,connet80,端口而生成的?,是不是,TCP,数据包里有什么特别的标志?,或者防火墙记住了什么东西?,6,(一),Socket,相关理论,类型,流式套接字(SOCK_STREAM),-,TCP,提供了一个面向连接、可靠的数据传输服务,数据无差错、无重复的发送且按发送顺序接收。内设置流量控制,避免数据流淹没慢的接收方。数据被看作是字节流,无长度限制。,数据报套接字(SOCK_DGRAM),-UDP,提供无连接服务。数据包以独立数据包的形式被发送,不提供无差错保证,数据可能丢失或重复,顺序发送,可能乱序接收。,7,Socket,的,位置,传输层,传输层,网络层,8,(一),Socket,相关理论,在,TCP,和,UDP,同属于传输层,共同架设在,IP,层(网络层)之上,。而,IP,层,主要负责的是在节点之间(,End to End,)的,数据包传送,,这里的节点是一台网络设备,比如计算机。因为,IP,层只负责把数据送到节点,,而不能区分上面的不同应用,,所以,TCP,和,UDP,协议在其基础上加入了端口的信息,,端口于是标识的是一个节点上的一个应用。除了增加端口信息,,UPD,协议基本就没有对,IP,层的数据进行任何的处理了。而,TCP,协议还加入了更加复杂的传输控制,比如滑动的数据发送窗口(,Slice Window,),以及接收确认和重发机制,以达到数据的可靠传送。,不管应用层看到的是怎样一个稳定的,TCP,数据流,下面传送的都是一个个的,IP,数据包,需要由,TCP,协议来进行数据重组。,所谓的,端口,,是为了区分不同的应用的,以在不同的,IP,包来到的时候能够正确转发。,9,(一),Socket,相关理论,可得出信息:,防火墙除了,获取,IP,地址和端口号,之外,,并没有足够的信息判断,TCP,数据包的更多信息。,所谓的端口,是为了区分不同的应用的,以在不同的,IP,包来到的时候能够正确转发,。,10,TCP/IP,只是一个协议栈,就像操作系统的运行机制一样,必须要具体实现,同时还要提供对外的操作接口,就像操作系统会提供标准的编程接口。,TCP/IP,引入了新型的“I/O”操作,-,Socket,编程接口,socket,的出现只是可以更方便的使用,TCP/IP,协议栈而已,其对,TCP/IP,进行了抽象,形成了几个最基本的函数接口。,比如,create,,,listen,,,accept,,,connect,,,read,和,write,等等。,(一),Socket,相关理论,11,如果一个程序创建了一个,socket,,并让其监听,80,端口,其实是向,TCP/IP,协议栈声明了其,对,80,端口的占有,。以后,所有目标是,80,端口的,TCP,数据包都会转发给该程序(这里的程序,因为使用的是,Socket,编程接口,所以首先由,Socket,层来处理)。,accept,函数返回的新,socket,其实指代的是本次创建的连接,,而一个连接是包括两部分信息的,一个是源,IP,和源端口,另一个是宿,IP,和宿端口。,(,所谓,accept,函数,其实抽象的是,TCP,的连接建立过程。,),(一),Socket,相关理论,12,所以,,accept,可以产生多个不同的,socket,,而这些,socket,里包含的,宿,IP,和宿端口是不变的,变化的只是源,IP,和源端口,。这样的话,这些,socket,宿端口就可以都是,80,,而,Socket,层还是能,根据源,/,宿对来准确地分辨出,IP,包和,socket,的归属关系,,从而完成对,TCP/IP,协议的操作封装!而同时,放火墙的对,IP,包的处理规则也是清晰明了,不存在前面设想的种种复杂的情形。,(一),Socket,相关理论,13,(二),TCP,的工作流程,2.1,服务器端工作流程,使用WSAStartup()函数检查系统协议栈安装情况,使用,socket()函数,创建服务器端通信套接口,使用,bind()函数,将创建的套接口与服务器地址绑定,使用,listen()函数,使服务器套接口做好接收连接请求准备,使用,accept()接收,来自客户端由connect()函数发出的连接请求,根据连接请求建立连接后,使用,send(),函数发送数据,或者使用,recv(),函数接收数据,使用closesocket()函数关闭套接口(可以先用shutdown()函数先关闭读写通道),最后调用WSACleanup()函数结束Winsock Sockets API,14,(二),TCP,的工作流程,2.2,客户端程序工作流程,使用WSAStartup()函数检查系统协议栈安装情况,使用socket()函数创建客户端套接口,使用,connect()函数,发出也服务器建立连接的请求(调用前可以不用bind()端口号,由系统自动完成),连接建立后使用send()函数发送数据,或使用recv()函数接收数据,使用closesocet()函数关闭套接口,最后调用WSACleanup()函数,结束Winsock Sockets API,15,2.3,服务器与客户端五元组的建立,16,2.4 TCP,的程序工作流程图,17,客户端的建立,相比于服务器,客户端就简单多了,因为它只需要一个,SOCKET,。,添加一个基于,CSocket,的子类,Client,,点击完成。这个类我们用于和客户端的连接和收发数据。,然后,在主对话框的头文件中添加,#include MySocket.h,,并且声明一个,Cilent,类,m_mySocket,;,接着,我们得再主对话框的,OnInitDialog,函数中添加,m_mySocket.Creat();,/,初始化,SOCKET,18,这时候,我们可以为主对话框添加一个按钮,,caption,设为,“,连接,”,,用于连接。双击这个按钮,开始函数定义,在函数体中我们加入以下代码:,m_mySocket.Connect(_,T(127.0.0.1),8888);,第一个参数表示想要连接的服务器的,IP,,第二个参数表示端口。,现在,客户端与服务器的连接工作已经做好了,我们需要再在客户端的主对话框中添加一个按钮,,caption,设为,“,发送,”,,用于发送信息,在改按钮的函数中,我们添加以下代码:,m_mySocket.Send(,客户端发来了信息,100);/,参数分别表示要发送的字符串和字符串的最大长度,.,19,服务端的建立:,添加一个基于,CSocket,的子类,Socket,,点击完成。这个类我们用于监听。,接下来呢,我们在,Socket,类函数实现中点属性,-,重写,-,OnAccept,。点属性,-,重写,-,OnReceive,。在,OnReceive,函数中,我们添加以下代码:,char str100;,Receive(str,100);,CString strtest;,strtest=str;,AfxMessageBox(strtest);,20,在,OnAccept,函数中,我们添加以下代码:,Socket SocketRev= new Socket ();,Accept(SocketRev);,这段代码的作用是在,当服务器监听到客户端的连接请求,时,新建一个,CRecv,的成员,并用它来接受客户端的连接请求,也就是,用它与客户端绑定,。,21,这段代码用于接收客户端发送过来的字符串,然后以,MessageBox,的形式显示出来。,最后,在主对话框的头文件中添加,#include Listen.h,,,并且声明一个,CListen,变,量,m_listen,。然后,在主对话框的,OnInitDialog,函数中,添加如下代码:,m_listen.Create,(8888);/8888,表示的是我们要监听的端口,m_listen.Listen();,22,(三),Socket,相关代码,3.1 Socket,基本函数的介绍,3.1.1,创建套接字,-Socket,应用程序在使用套接口通信前,必须要拥有一个套接口,,使用socket()函数来给应用程序创建一个套接口。,SOCKET socket(,int af,/,要使用的协议地址族,int type,/,描述套接口的类型,int protocol,/,该套接口使用的特定协议,);,23,af参数,:,说明套接字接口要使用的协议地址族,地址族与协议族含义相同。如果想建立一个TCP或UDP,只能用常量,。,AF_INET,参数,表示使用互联网协议(IP)地址。Winsock还支持其他协议,但一般很少使用。,type参数,:,描述套接口的类型,af是AF_INET的时候只能为SOCK_STREAM、SOCK_DGRAM或SOCK_RAW,P,rotocol,参数,:,说明该套接口使用的特定协议,当协议地址族af和协议类型type确定后,协议字段可以使用的值是限定的,socket()参数说明,24,3.1.2,将创建的套接口与服务器地址绑定,bind(),当socket()创建了一个套接口后,,需要将该套接口与该主机上提供服务的某端口联系在一起,,bind()函数用于完成这样的绑定。,int bind(,SOCKET s,/,标识一个未绑定的套接口描述字,const struct sockaddr FAR * name,/,存储了套接口的地址信息,int namelen,/,地址参数(name)的长度,);,25,S,参数,:,标识一个未绑定的套接口描述字,它是socket()函数调用成功时返回的值,name,参数,:,是一个与指定协议有关的地址结构指针,存储了套接口的地址信息,Winsock中使用sockaddr_in结构指定IP地址和端口信息,struct sockaddr_in,short sin_family;,u_short sin_port;,struct in_addrsin_addr;,char,sin_zero8;,sin_family一般为AF_INET,表示使用IP地址族;sin_port是以网络字节序表示的16位端口号;sin_addr是网络字节序的32位IP地址;sin_zero字段一般不用,用0填充,namelen,参数,:,表示地址参数(name)的长度,IP地址参数为INADDR_ANY,则由系统内核来自动指定,port为0,则由系统自动指派一个10245000之间惟一的端口号,bind()参数说明,26,3.1.3,服务器端启动监听listen()函数,在一个服务器端用socket()调用成功创建了一个套接口,并用bind()函数和一个指定的地址关联后,就需要指示该套,接口进入监听连接请求状态,这需要通过listen()函数来实现,int,listen(,SOCKET,s,int,backlog,);,S,参数:,代表一个已绑定了地址,但还未建立连接的套接口描述字,B,acklog,参数:,指定了正在等待连接的最大队列长度,27,3.1.4,服务器端接受连接accept()函数,在服务器端通过listen()函数调用表示服务器进入监听客户的连接请求状态,而在服务器端调用accept()函数时表示可以,接收来自客户端由connect()发出的连接请求,,双方进入连接状态。,SOCKET,accept(,SOCKET,s,/,s标识一个套接字,struct sockaddr FAR *,addr,/,用来存放发出连接请求的那个客户机的IP地址信息,int FAR *,addrlen,/,指出客户套接口地址结构的长度,);,28,s,参数,:,标识一个套接字,该套接口处于监听状态,addr,参数,:,是一个地址结构的指针,用来存放发出连接请求的那个客户机的IP地址信息,addrlen,参数,:,指出客户套接口地址结构的长度,函数说明:该函数用于面向连接的服务器端,在IP协议族中,只用于TCP服务器端,accept()函数参数说明,29,3.1.5,发送数据-send()函数,在已经建立连接的套接口上,发送数据,,可以使用send()函数,int send(,SOCKET s,/,用于标识已建立连接的套接字,const char FAR * buf,/,是一个字符缓冲区,内有将要发送的数据,int len,/,即将发送的缓冲区中的字符数,int flags,/,用于控制数据传输方式,);,30,s,参数,:,用于标识已建立连接的套接字,buf,参数,:,是一个字符缓冲区,内有将要发送的数据,len,参数,:,即将发送的缓冲区中的字符数,flags,参数,:,用于控制数据传输方式,0表示按正常方式发送数据;宏MSG_DONTROUTE说明系统目标主机就在直接连接的本地网络中,无需路由选择;MSG_OOB指出数据是按带外数据发送的,函数说明:send()函数适用于已建立连接的数据报或流式套接口发送数据,对于数据报类型套接口必须注意发送数据长度不大于通信子网的IP包最大长度,send()函数参数说明,31,3.1.6,接收数据,recv(),函数,对于已建立连接的套接口来说,要从套接口上,接收数据,,就要使用recv()函数。,int recv(,SOCKET s,/,已建立连接的套接口,char FAR * buf,/,为用于接收数据的缓冲区,int len,/,为缓冲区的长度,int flags,/,指定调用的方式,);,32,recv()函数参数说明,s,参数,:,为已建立连接的套接口,buf,参数:,为用于接收数据的缓冲区,len,参数,;,为缓冲区的长度,flags,参数,:,指定调用的方式。0表示接收的是正常数据,无特殊行为。MSG_PEEK表示会使有用的数据复制到所提供的接收端缓冲区内,但是没有从系统缓冲区中将数据删除。MSG_OOB表示处理带外数据。,33,3.1.7,关闭套接口-closesocket()函数,一个套接口不再使用时一定要关闭这个套接口,以释放与该套接口关联的所有资源,包括等候处理的数据。,int closesocket(,SOCKET s,);,参数s,:,表示即将被关闭的套接口,34,3.1.8,客户端请求连接connect()函数,当服务器端建立好套接口并与一个本地地址绑定后,就进入监听状态,等待客户发出连接请求。在客户端套接口建立好之后,就调,用connect()函数来与服务器建立连接,。,int,connect(,SOCKET,s,/,将要建立连接的套接口描述字,const struct sockaddr FAR *,name,/,是一个指向远端套接口地址结的指针,int,namelen,/,服务器端的地址长度,);,35,s,参数:,将要建立连接的套接口描述字,name,参数:,是一个指向远端套接口地址结(sockaddr_in)的指针,表示s套接口欲与其建立一条连接,namelen,参数:,是服务器端的地址长度,即name的长度,connect()函数参数说明,36,
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 图纸专区 > 大学资料


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!