1.close()函数:立即返回到进程

int close(int sockfd);     //返回成功为0,出错为-1.

close 一个套接字的默认行为是把套接字标记为已关闭,然后立即返回到调用进程,该套接字描述符不能再由调用进程使用,也就是说它不能再作为read或write的第一个参数,然而TCP将尝试发送已排队等待发送到对端的任何数据,发送完毕后发生的是正常的TCP连接终止序列。

在多进程并发服务器中,父子进程共享着套接字,套接字描述符引用计数记录着共享着的进程个数,当父进程或某一子进程close掉套接字时,描述符引用计数会相应的减一,当引用计数仍大于零时,这个close调用就不会引发TCP的四路握手断连过程。

(假设服务器server端调用close)

如果server的socket套机字的接收缓冲区,还有数据未被应用进程读取,则server直接发送RST报文给client。

如果接收缓冲区没有数据了,但是发送缓冲区还有数据未被发送,则会尝试先发送此部分数据,然后才是发送FIN报文。

通过设置SO_LINNGER套接字口选项,可以改变缺省的功能。

struct linger {
    int onoff; /* 0=off, nonzero=on */
    int l_linger; /* linger time, POSIX specifies units as seconds */
};

1. close后,默认情况与使用l_onoff=0效果一致,本方继续接收数据并ACK,但会丢弃这些数据,直到对方FIN过来,完成连接终止过程;
2. close后,l_onoff非0且l_linger=0,立即丢弃发送缓存区数据并给对方发送一个RST,也就是不会有正常的四分组终止过程,也没有TIME_WAIT,对方收到RST后,肯定不能继续发数据了;
3. close后,l_onoff非0且l_linger>0,设置拖延时间,内核拖延,close会等待l_linger(阻塞情况下),两种可能,在延迟时间到达之前,数据发送完毕且被对方确认,或者延迟时间到了,通过进程检查close返回值判别,是那种情况,若是第二种,而返回ewouldbloack,且发送缓冲区的所有数据都丢失。

只要l_onoff为0,无论l_linger为什么值,都跟缺省情况完全一样

如果close造成的是发送FIN,在这之后,对方继续发送data 过来的话呢?
按照底层TCP协议,local侧是否继续发送ack of data给对方,直到local侧buffer满了
因为TCP两方的通信通道,local侧永远只能掌控local侧出去的方向,不能控制对方侧继续发送数据。即在FIN_WAIT2状态时,local侧依然可以接收对方的data

注意:缺省的情况下,server close(fd),且发送FIN给client之后,client端还是可以发送数据给server,只是server只是接收client发送到接收缓冲区的数据,然后全部丢失,也不应答。

2、shutdown()函数

int shutdown(int sockfd,int howto);  //返回成功为0,出错为-1

shut_rd:关闭读这一半,在接收缓冲区的数据全部丢失,进程不能对此socket执行任何读操作,但是对方还是可以发送数据到此socket的接收缓冲区,且发送应答ack,只是接收缓冲区的数据全部丢失

shut_wr:关闭写一半,当前在发送缓冲区的数据首先被发送,然后才是FIN报文(这跟close一样),但是此函数不管套接字描述符的引用计数是否为0,都会执行操作,这根close不同。

两者之间比较:
close和shutdown的行为取决于内核的实现。
1. close调用之后如果在local TCP buffer内如果还有数据没有读取会给对方直接回RST, 否则发送FIN,这取决于调用close时刻local TCP buffer的状态, 跟对端是不是继续发送数据无关。
2. shutdown关闭读不会给对方发FIN, 只有关闭写才会发FIN, 而且跟local TCP buffer状态没关系,只发送FIN包,从不发送RST

设置l_onoff为非0,l_linger为非0,那么一种可能的情况是,在延迟时间到达之后,收到数据确认和FIN确认,此时close才返回,这告诉我们,发送的数据和FIN都被对方确认了。但是他不能告诉我们,数据是否被对方应用进程读取。但是不设置这个选项,连对方TCP是否确认了数据都不知道。

让client知道server读取了其数据的解决方法:

调用shutdown,之后read堵塞,直到对方的FIN发来(因为对方应用层读取数据和FIN之后,调用close),read才返回0.

socket 释放全过程的更多相关文章

  1. 二. Socket用法

    C/S通信架构中,客户端要主动与服务端建立连接,这个链接就是Socket套接字.服务端收到连接请求后,也会开启Socket记录与客户端的链接.C/S两端都要建路Socket才能正常收发数据. 一.构造 ...

  2. SO_REUSEADDR和SO_REUSEPORT异同

    文章内容来源于stackoverflow上的回答,写的很详细http://stackoverflow.com/questions/14388706/socket-options-so-reuseadd ...

  3. tcp_tw_recycle和tcp_timestamps的文章汇总

        临近年关,人会变得浮躁,期间写的代码可谓乱七八糟.不过出来混始终是要还的,这不最近就发现一个PHP脚本时常连不上服务器. 遇到这类问题,我习惯于先用strace命令跟踪了一下看看: shell ...

  4. hibernate 3.* C3P0配置 以及为什么需要连接池!

    Hibernate自带的连接池算法相当不成熟. 它只是为了让你快些上手,并不适合用于产品系统或性能测试中. 出于最佳性能和稳定性考虑你应该使用第三方的连接池.只需要用特定连接池的设置替换 hibern ...

  5. 消息队列NetMQ 原理分析3-命令产生/处理和回收线程

    消息队列NetMQ 原理分析3-命令产生/处理和回收线程 前言 介绍 目的 命令 命令结构 命令产生 命令处理 创建Socket(SocketBase) 创建连接 创建绑定 回收线程 释放Socket ...

  6. Linux内核中网络数据包的接收-第一部分 概念和框架

    与网络数据包的发送不同,网络收包是异步的的.由于你不确定谁会在什么时候突然发一个网络包给你.因此这个网络收包逻辑事实上包括两件事:1.数据包到来后的通知2.收到通知并从数据包中获取数据这两件事发生在协 ...

  7. 【转】tcp_tw_recycle和tcp_timestamps导致connect失败问题

    (2012-02-01 18:40:32)     近来线上陆续出现了一些connect失败的问题,经过分析试验,最终确认和proc参数tcp_tw_recycle/tcp_timestamps相关: ...

  8. UDP收/发广播包原理及步骤

    原文链接地址:http://www.2cto.com/net/201311/254834.html UDP收/发广播包原理及步骤 如果网络中两个主机上的应用程序要相互通信,其一要知道彼此的IP,其二要 ...

  9. 浅析套接字中SO_REUSEPORT和SO_REUSEADDR的区别

    Socket的基本背景 在讨论这两个选项的区别时,我们需要知道的是BSD实现是所有socket实现的起源.基本上其他所有的系统某种程度上都参考了BSD socket实现(或者至少是其接口),然后开始了 ...

随机推荐

  1. 发RTX通知

    安装sdk 在RTXServer目录下找到WebRoot目录,找到里面的SendNotify.cgi(就是一个php页面,默认是pc - ascii编码).打开页面,在头部加上编码信息 header( ...

  2. logstash日志写入kafka

    安装kafka curl -L -O https://mirrors.cnnic.cn/apache/kafka/0.10.2.1/kafka_2.10-0.10.2.1.tgz tar xf kaf ...

  3. python3-password在输入密码时隐藏密码

    # Auther: Aaron Fan #这个脚本请在命令行去执行才可以试出效果,pycharm这里无法测试这个脚本,切记!import getpass _username = "Aaron ...

  4. 理解JSON的语法

    JSON语法可以分为三种类型: 简单值 对象 数组 简单值: 5 "Hello World" JavaScript字符串与JSON字符串的最大区别在于,JSON字符串必须使用双引号 ...

  5. C++笔记--指针数组和结构

    指针 类型为T*的变量能保存一个类型T对象的地址 Char c=‘a’:Char * p=& c://保存了c的地址 指针的操作一般都是间接的引用,就是相当于引用指针所指的对象. 0是一个特殊 ...

  6. POJ 2686 Traveling by Stagecoach (状压DP)

    题意:有一个人从某个城市要到另一个城市, 有n个马车票,相邻的两个城市走的话要消耗掉一个马车票.花费的时间呢,是马车票上有个速率值 ,问最后这个人花费的最短时间是多少. 析:和TSP问题差不多,dp[ ...

  7. 【Arcgis for android】保存地图截图到sd卡

    关键词:arcgis for android ,截图,bitmap,sd卡 参考文章:http://blog.csdn.net/wozaifeiyang0/article/details/767972 ...

  8. dojo1.7 加载器

    原文地址:http://dojotoolkit.org/documentation/tutorials/1.7/modules/ dojo现在支持在异步模块异步(AMD)定义中加入模块写入功能了,这使 ...

  9. ASP.NET常用数据绑定控件优劣总结

    本文的初衷在于对Asp.net常用数据绑定控件进行一个概览性的总结,主要分析各种数据绑定控件各自的优缺点,以便在实际的开发中选用合适的控件进行数据绑定,以提高开发效率. 因为这些数据绑定控件大部分都已 ...

  10. c#百分比计算

    //此方法得到的百分比后小数太多,不行double percent=Convert.ToDouble(2)/Convert.ToDouble(34); string result=(percent*1 ...