网络软件设计——拆除连接.pptx
1拆除连接所以,什么叫“通信结束”?双方都了解对方没有新的数据时怎样“结束”连接?核心问题怎样了解对方没有新数据?怎样被对方了解自己没有新数据?第1页/共17页2拆除连接连接关闭的相关问题有没有多种选择?如关闭双向连接中的一向shutdown(s,SD_SEND);shutdown(s,SD_RECV);对待发/待收数据的处理?如一方强行断链系统发送完待发数据系统丢弃所有的数据要不要释放资源?可否继续利用套接字建立新的连接新的连接新的套接字第2页/共17页3拆除连接“通信结束”的方法讨论联想日常生活中,挂电话的情况1、两个人商量好,然后各自挂机过于依赖高层协议,有碍服务器程序的通用性2、一方挂机,另一方听到忙音后挂机过于粗暴3、对于双向通信,A方通知“我没有新数据”了,B方收到通知后,发完自己的数据后就可以挂机了。可以让双方的数据都得到完整交换雅致关闭设计设计第3页/共17页4拆除连接分别设计各种方式的算法高层协商粗暴关闭雅致关闭第4页/共17页5拆除连接拆除连接1 1、两个人商量好,然后各自挂机、两个人商量好,然后各自挂机A AB B(want to cease the conversation)want to cease the conversation)data=“I want to stop”;data=“I want to stop”;send(data);send(data);recv(data);recv(data);recv(data);recv(data);if(data=“I want to stop”)if(data=“I want to stop”)if(state=AGREE)if(state=AGREE)send(“I agree”);send(“I agree”);if(data=“I agree”)if(data=“I agree”)closesocket(s);closesocket(s);goto end;goto end;elseelsecontinue conversationcontinue conversation goto back;goto back;closesocket(s);closesocket(s);goto end;goto end;elseelsesend(“I have more words”)send(“I have more words”)continue conversationcontinue conversation 第5页/共17页6拆除连接拆除连接2 2、一方挂机,另一方听到忙音后挂机、一方挂机,另一方听到忙音后挂机A AB B(want to cease the conversation)want to cease the conversation)closesocket(s);closesocket(s);send(data);send(data);if(recv(data)=0)if(recv(data)0)while(recv(data)0)continue conversation;continue conversation;closesocket(s);closesocket(s);第6页/共17页73 3、对于双向通信,、对于双向通信,A A方通知方通知“我没有新数据我没有新数据”了,了,B B方收到通知方收到通知在发完数据后就可以挂机了。在发完数据后就可以挂机了。拆除连接拆除连接A AB B(want to cease the conversation)want to cease the conversation)if if(state=NO_DATA_SEND)state=NO_DATA_SEND)shutdown(SD_SEND);shutdown(SD_SEND);if(recv(data)=0)if(recv(data)0)while(recv(data)0)process data;process data;closesocket(s);closesocket(s);雅致关闭雅致关闭思考:在思考:在process dataprocess data中中如果需要发出数据怎么办?如果需要发出数据怎么办?第7页/共17页8雅致关闭“雅致”关闭是计算机通信系统的特色“雅致”关闭可以使双方的数据都能完整接收/发送雅致关闭有多种方式(算法)可以实现注意雅致关闭与高层协商的区别!高层协商的缺点在于协商的可靠性不高雅致关闭的优点在于通过系统来通报希望结束的信息,提高了通用性和可靠性,降低了实现难度用户通知系统(“我没有数据了”)shutdown(SD_SEND);系统通知用户(“对方没有数据了”)recv()函数的返回值为0!第8页/共17页9雅致关闭的实现方法一、利用shutdown标准做法算法思路A AB B无需要发送的数据后无需要发送的数据后shutdownshutdown(SD_SENDSD_SEND););可以接收对方的数据直到可以接收对方的数据直到对方关闭套接字对方关闭套接字closesocketclosesocket()()whilewhile(recvrecv(datadata)0)0)process(data);process(data);if(recv(data)=0)if(recv(data)=0)send(data)send(data)closesocket()closesocket()雅致关闭并不对服务器和客户机程序有所区分雅致关闭并不对服务器和客户机程序有所区分第9页/共17页10雅致关闭的实现方法一、利用shutdown标准做法算法if if(状态为发送完毕)(状态为发送完毕)shutdown(SD_SEND);shutdown(SD_SEND);while(recv()0)while(recv()0)processdata();processdata();closesocket();closesocket();elseelsesend();send();if(recv()0)if(recv()0)processdata();processdata();elseelseshutdown(SD_RECV);shutdown(SD_RECV);第10页/共17页11socket函数与时序函数与时序SYNSYNSYN+ACKSYN+ACKACKACKFINFINFINFINACKACKlistenlisten()()connectconnect()()connect()connect()返回返回acceptaccept()()sendsend()()sendsend()()recvrecv()()recvrecv()()shutdownshutdown(SENDSEND)closesocketclosesocket()()recvrecv()的返回()的返回recvrecv()()recvrecv()的返回值()的返回值=0=0ACKACKrecvrecv()()recvrecv()的返回值()的返回值=0=0closesocketclosesocket()()第11页/共17页12雅致关闭方法二、利用closesocket()不限时逗留设置套接字状态为SO_DONTLINGER SO_DONTLINGER为套接字默认状态调用closesocket();系统并没有将套接字立即关闭,而是在发完套接口结构中待发送队列上的所有数据后才关闭struct socketstruct socketshort so_type;short so_type;short so_state;short so_state;struct sockbuf struct sockbuf so_rcv,so_rcv,so_sndso_snd;第12页/共17页13雅致关闭方法三、利用closesocket()限时逗留设置套接字状态为SO_LINGER,并设置逗留的时间超时时间为非零值调用closesocket();系统并没有将套接字立即关闭,而是在发完套接口结构中待发送队列上的所有数据后,或超时后才关闭若超时还有数据没有发完,只有丢弃数据,完成关闭动作第13页/共17页14立即关闭丢弃所有待发送/接收数据的方法设置套接字为SO_LINGER,并设置逗留时间为0调用closesocket(),socket会立即关闭,资源立即释放注:TCP层实体此时配合发送的是RST报文struct linger immediately;struct linger immediately;immediately.l_onoff=1;immediately.l_onoff=1;immediately.l_linger=0;immediately.l_linger=0;val=setsockopt(sock,SOL_SOCKET,SO_LINGER,val=setsockopt(sock,SOL_SOCKET,SO_LINGER,(char*)&immediately,sizeof(immediately);(char*)&immediately,sizeof(immediately);closesocket(sock);closesocket(sock);第14页/共17页15socketsocketTCP/UDPTCP/UDP应用进程应用进程socket结构里的队列结构里的队列so_q0so_q0so_qso_qso_rcvso_rcvso_sndso_snd数据到达数据到达送出数据送出数据shutdownshutdown()()closesocketclosesocket()()RECVRECV:关闭:关闭so_rcvso_rcv队列、释放数据队列、释放数据SENDSEND:关闭:关闭so_sndso_snd队列队列 发完发完so_sndso_snd队列上现有数据队列上现有数据DONTLINGERDONTLINGER:关闭:关闭so_rcvso_rcv队列队列 发完发完so_sndso_snd上所有数据上所有数据立即关闭:关闭并释放立即关闭:关闭并释放so_rcvso_rcv队列队列 关闭并释放关闭并释放so_sndso_snd队列队列第15页/共17页16拆除连接小结小结shutdown和closesocket都可以实现关闭连接,但有不同。shutdown的雅致关闭可以保证高层数据的完整交换closesocket的“雅致关闭”只能保证TCP实体间的数据完整性shutdown不释放套接字资源注:是否可继续利用套接字,请大家测试closesocket释放套接字资源结合队列理解雅致关闭的实现方法,可以帮助我们丰富在模块间设计接口队列的经验第16页/共17页17感谢您的观看!第17页/共17页