《网络软件设计15——拆除连接.ppt》由会员分享,可在线阅读,更多相关《网络软件设计15——拆除连接.ppt(18页珍藏版)》请在三一文库上搜索。
1、网络软件设计,拆除连接,制作 主讲,段景山,2,连接的拆除,传完了数据就该结束了 But,To be, or not to,its a problem 结束,还是不结束,这是个问题 不恰当的结束将导致通信的失败 失败的通信是前功尽弃的 例 什么原因可能导致通信失败? 当自己没有数据时,就结束 错误根源:以自己的状态来评判对方的状态 当自己没有数据时不结束 容易出现死锁,P88/P105/P112/P114,1、客户发出请求后等待服务器的数据 2、服务器发送完数据后等待客户机新的请求 3、如果客户机不知道服务器有多少数据时,死锁! 4、同理,若服务器不知道客户机有没有新请求时,死锁!,3,拆除连
2、接,所以,什么叫“通信结束”? 双方都了解对方没有新的数据时 怎样“结束”连接? 核心问题 怎样了解对方没有新数据? 怎样被对方了解自己没有新数据?,4,拆除连接,连接关闭的相关问题 有没有多种选择?如关闭双向连接中的一向 shutdown(s,SD_SEND); shutdown(s,SD_RECV); 对待发/待收数据的处理?如一方强行断链 系统发送完待发数据 系统丢弃所有的数据 要不要释放资源? 可否继续利用套接字建立新的连接 新的连接新的套接字 ,5,拆除连接,“通信结束”的方法讨论 联想日常生活中,挂电话的情况 1、两个人商量好,然后各自挂机 过于依赖高层协议,有碍服务器程序的通用性
3、 2、一方挂机,另一方听到忙音后挂机 过于粗暴 3、对于双向通信,A方通知“我没有新数据”了,B方收到通知后,发完自己的数据后就可以挂机了。 可以让双方的数据都得到完整交换 雅致关闭,设计,6,拆除连接,分别设计各种方式的算法 高层协商 粗暴关闭 雅致关闭,7,拆除连接,1、两个人商量好,然后各自挂机,A,B,(want to cease the conversation),data = “I want to stop”;,send(data);,recv (data);,recv(data);,if(data = “I want to stop”),if(state = AGREE),sen
4、d(“I agree”);,if(data = “I agree”),closesocket(s);,goto end;,else,continue conversation,goto back;,closesocket(s);,goto end;,else,send(“I have more words”),continue conversation,8,拆除连接,2、一方挂机,另一方听到忙音后挂机,A,B,(want to cease the conversation),closesocket(s);,send(data);,if( recv(data) = 0 ),closesocket
5、(s);,goto end;,else,continue conversation;,注意:want to cease the conversation往往是由于自己没有 新数据要发。但,不意味着知道对方没有新的数据送来,此时 关闭连接是不妥当的,while(recv(data) 0) continue conversation; closesocket(s); ,9,3、对于双向通信,A方通知“我没有新数据”了,B方收到通知 在发完数据后就可以挂机了。,拆除连接,A,B,(want to cease the conversation),if(state = NO_DATA_SEND),shu
6、tdown( SD_SEND );,if(recv( data ) = 0 ),state = CLOSE_WAIT;,send( data );,if( state = NO_DATA_SEND),closesocket(s);,goto end;,else,goto back;,while(recv(data)0),process data;,closesocket(s);,雅致关闭,思考:在process data中 如果需要发出数据怎么办?,10,雅致关闭,“雅致”关闭是计算机通信系统的特色 “雅致”关闭可以使双方的数据都能完整接收/发送 雅致关闭有多种方式(算法)可以实现 注意雅致关
7、闭与高层协商的区别! 高层协商的缺点在于协商的可靠性不高 雅致关闭的优点在于通过系统来通报希望结束的信息,提高了通用性和可靠性,降低了实现难度 用户通知系统(“我没有数据了”) shutdown(SD_SEND); 系统通知用户(“对方没有数据了”) recv()函数的返回值为0!,11,雅致关闭的实现,方法一、利用shutdown标准做法 算法思路,A,B,无需要发送的数据后,shutdown(SD_SEND);,可以接收对方的数据直到 对方关闭套接字,closesocket(),while(recv(data)0) process(data);,if(recv(data) = 0),sen
8、d(data),closesocket(),雅致关闭并不对服务器和客户机程序有所区分,12,雅致关闭的实现,方法一、利用shutdown标准做法 算法,if(状态为发送完毕),shutdown( SD_SEND );,while( recv( ) 0 ),processdata( );,closesocket( );,else,send( );,if( recv( ) 0 ),processdata( );,else,shutdown( SD_RECV);,13,socket函数与时序,SYN,SYN+ACK,ACK,FIN,FIN,ACK,listen(),connect(),connect
9、()返回,accept(),send(),send(),recv(),recv(),shutdown(SEND),closesocket(),recv()的返回,recv(),recv()的返回值=0,ACK,recv(),recv()的返回值=0,closesocket(),14,雅致关闭,方法二、利用closesocket( )不限时逗留 设置套接字状态为SO_DONTLINGER SO_DONTLINGER为套接字默认状态 调用closesocket(); 系统并没有将套接字立即关闭,而是在发完套接口结构中待发送队列上的所有数据后才关闭,struct socket short so_ty
10、pe; short so_state; struct sockbuf so_rcv, so_snd; ,15,雅致关闭,方法三、利用closesocket()限时逗留 设置套接字状态为SO_LINGER,并设置逗留的时间 超时时间为非零值 调用closesocket(); 系统并没有将套接字立即关闭,而是在发完套接口结构中待发送队列上的所有数据后,或超时后才关闭 若超时还有数据没有发完,只有丢弃数据,完成关闭动作,16,立即关闭,丢弃所有待发送/接收数据的方法 设置套接字为SO_LINGER,并设置逗留时间为0 调用closesocket(), socket会立即关闭,资源立即释放 注:TCP
11、层实体此时配合发送的是RST报文,struct linger immediately; immediately.l_onoff = 1; immediately.l_linger = 0; val = setsockopt(sock,SOL_SOCKET,SO_LINGER, (char *),17,socket,TCP/UDP,应用进程,socket结构里的队列,so_q0,so_q,so_rcv,so_snd,数据到达,送出数据,shutdown(),closesocket(),RECV:关闭so_rcv队列、释放数据,SEND:关闭so_snd队列 发完so_snd队列上现有数据,DONTLINGER:关闭so_rcv队列 发完so_snd上所有数据,立即关闭:关闭并释放so_rcv队列 关闭并释放so_snd队列,18,拆除连接小结,小结 shutdown和closesocket都可以实现关闭连接,但有不同。 shutdown的雅致关闭可以保证高层数据的完整交换 closesocket的“雅致关闭”只能保证TCP实体间的数据完整性 shutdown不释放套接字资源 注:是否可继续利用套接字,请大家测试 closesocket释放套接字资源 结合队列理解雅致关闭的实现方法,可以帮助我们丰富在模块间设计接口队列的经验,
链接地址:https://www.31doc.com/p-2920297.html