博主是搞是个FPGA的,一直没有真正的研究过以太网相关的技术,现在终于能静下心学习一下,希望自己能更深入的掌握这项最基本的通信接口技术。下面就开始搞了。
一、OSI参考模型
记录-交流-Web开发知识分享
博主是搞是个FPGA的,一直没有真正的研究过以太网相关的技术,现在终于能静下心学习一下,希望自己能更深入的掌握这项最基本的通信接口技术。下面就开始搞了。
一、OSI参考模型
PHP 实现websocket…
HTML5 服务器发送事件(server-sent event)允许网页获得来自服务器的更新。
Server-Sent 事件指的是网页自动获取来自服务器的更新。
以前也可能做到这一点,前提是网页不得不询问是否有可用的更新。通过服务器发送事件,更新能够自动到达。
例子:Facebook/Twitter 更新、估价更新、新的博文、赛事结果等。
以下面这段代码并不会逐个输出,而是当浏览器筹够一定字节数进行统一输出,结果显而易见,10秒后一次性输出所有内容…
PHP 里开启实时输出方法是ob_implicit_flush()
,
但它大部分情况下都不管用,
因为php.ini
配置里output_buffering
输出缓冲大部分是On
开启的,
还有zlib.output_compression
也经常会被开启,
除了 PHP 这一层,还有 Nginx 的缓冲设置proxy_buffering
,和压缩gzip
也大都是开启的。
为了一两个页面的需求,修改整个服务器的网站配置,恐怕没有人会做这种选择。
这里推荐一下简单的方法:
…这段时间又攒了很多答应了,但还未动手的文章。大概一两周前,有个读者留言:「程序君,能发篇文章有关编程思想的吗?我是编程初学者,对编程思想没啥概念,求传授点经验!」
今天就讲讲编程思想。编程思想是个宏大的主题,我不敢保证我能在短短的一两个小时里讲得全面而深入。推荐给大家一本好书『冒号课堂』,是国内为数不多的讲编程思想的经典之作。无奈这本书已经不再出版,只能在图书馆里一睹芳容(我几年前在国图和它偶遇)。
各种软件思想虽然层出不穷,但其本质是降低系统复杂度,减少重复,减少代码的变更。掌握了这个大方向,理解各种编程思想就容易多了。
(下文所涉及的代码大多是剪短清晰的python代码)
以程序君不太准确的分类,编程思想可以分为以下几个大类:
我们一点点展开,说到哪算哪。
我认识(或者说现在想得起来的)的原则主要有以下几种:
"Don't repeat yourself"很好理解。当你第二次写同样结构,变化不大的代码时,脑袋里就要闪现一个大大的问号:我是不是在repeat myself?如果是,就要重构,或封装,或抽象,或函数化,总之一个目的,消除重复。以笔者的经验,DRY原则看似基本,实则很多大型软件公司都未能做好,copy & paste到处可见。我们写代码,从一开始就要把握好这个原则,否则在「破窗理论」的指引下,代码的质量会快速划向万劫不复的深渊。
要不要转行(报考)软件开发?程序员的高薪让我流口水,但好日子总有个到头的时候吧?不会我一入行就见顶了吧?
这样的问题让我不胜其烦。为子女未来前途操碎了心的长辈们,长辈们的朋友们,还有微信知乎上的朋友,像候鸟一样,在一年里的两个时间:春节期间和高考报志愿前夕,准时开问。我大概六月份回答过一位长辈的咨询,他说小陈,你说的好像很有道理的样子啊,应该发篇文章我好能转给我的朋友们。我说叔叔好啊,就写就写。结果开了个头,就因为懒的原因(主要是红包没到位),一直搁在今天。最近翻看 git repo 里面一票未完成的文章,这篇蹦了出来,伸长脖子一个劲儿地向我示意:poke me,poke me,所以,就有了大家看到的这篇文章。…
多线程多进程关闭连接的区别
首先来看看close和shutdown两个系统调用对应的内核函数:
上图是调用close和shutdown关闭连接时的函数调用过程,sys_close和sys_shutdown这两个系统调用最终是由tcp_close和tcp_shutdown方法来实现的。
由此我们可以来看一个问题:当socket被多进程或者多线程共享时,关闭连接时有何区别?
从图中可以看到sys_close封装调用过程中有一个fput函数,它有一个引用计数,记录这个socket被引用了多少次。当这个引用计数不为0时,是不会触发真正关闭tcp连接的tcp_close方法的。
引用计数是怎么来的呢?创建进程和线程都是由clone系统调用实现的,只不过clone的参数不同,行为也不同。
在clone系统调用中,会调用方法copy_files来拷贝文件描述符(包括socket)。创建线程时,传入的flag参数中包含标志位CLONE_FILES,此时,线程将会共享父进程中的文件描述符。
而创建进程时没有这个标志位,这时,会把进程打开的所有文件描述符的引用计数加1。所以子进程会将父进程中已经建立的socket加上引用计数,当进程中close一个socket时,只会减少引用计数,仅当引用计数为0时才会触发tcp_close。
单线程(进程)中使用close与多线程中是一致的,但这两者与多进程的行为并不一致,多进程中共享的同一个socket必须都调用了close才会真正的关闭连接。
shutdown是没有引用计数什么事的,只要调用了就会去试图按需关闭连接。所以shutdown与多线程、多进程无关。
close发生了什么
TCP连接是全双工的连接,及连接双方可以并行的发送或者接收消息。这样关闭连接时就存在3种情形:完全关闭连接; 关闭发送消息的功能;关闭接收消息的功能。其中,后者就叫做半关闭,由shutdown实现,前者用close实现。
我们现在来看看close。
我们依次来看一下这三种情形:
1)关闭监听句柄
用于listen的监听句柄是close关闭的,它本身并不对应着某个连接,但是附着在它之上的却可能有半成品连接,即1、2次握手完成,第3次未完成,就会在服务器上有许多半连接,close的工作主要是清理这些半连接。
keepalive定时器是干嘛的?keepalive是TCP中一个可以检测死连接的机制,侧重在保持客户端和服务端的连接,防止僵死、异常退出的客户端占用服务器连接资源。
比如A与B建立连接后,突然B宕机了,之后时间内B再也没有起来,如果B宕机后A和B一直没有数据通信的需求,A就永远不会发现B已经挂了,那么A的内核里还维护着一份关于A与B之间TCP连接的信息,浪费系统资源。
所以TCP层面引入了keepalive机制,A会定期给B发送空的数据包,通俗讲就是心跳包。
内核对于tcp keepalive的调整主要有以下三个参数:
当tcp发现未收到对端数据时,开始以间隔tcp_keepalive_intvl(75)秒的频率发送心跳包。
如果连续tcp_keepalive_probes(9)次以上未响应代表对端已经down了,close该连接。
参照上图,close首先会移除keepalive定时器,移除此定时器后,若ESTABLISH状态的TCP连接在tcp_keepalive_time时间(如服务器上常配置为2小时)内没有通讯,服务器就会主动关闭连接。接下来,发送RST包去关闭每一个半连接,处理完所有半打开的连接close的任务就基本完成了。
2)关闭普通ESTABLISH状态的连接(未设置so_linger,默认)
首先检查是否有接收到却未处理的消息。如果有,根据close的行为是要丢掉这些消息的。
但丢弃消息后,意味着远端误以为发出的消息已经被本机处理了(因为ACK包确认过了),但实际上是收到未处理,此时不能使用正常的四次握手关闭连接,而是会向远端发送一个RST非正常复位关闭连接。所以这要求程序员在关闭连接前,确保接收并处理了连接上的消息。
如果此时没有未处理的消息,那么发送FIN来关闭连接。这时,再看看是否有待发送消息,如果有,那么会在最后一个报文中加入FIN标志,同时关闭angle算法,一次性将所有包发出;如果没有未发送消息,则仅发送一个FIN报文,发送出去关闭连接。
3)使用了so_linger的连接
so_linger是干嘛的?so_linger决定系统如何处理残留在套接字发送队列中的数据。我们可能有强可靠性的需求,也就是说,必须确保发出的消息、FIN都被对方收到。
怎么做到呢?就是等待,close会阻塞住进程,直到对方确认收到了再返回,但是如果对方总是不响应怎么办呢?所以还需要l_linger这个超时时间,控制close阻塞进程的最长时间。
上图是l_linger参数的设置及其对应的行为,默认情况下是第一种情况。
当使用了so_linger后,前半段仍然没有变化。首先检查是否有未处理消息,有则发RST关连接。
接下来检查是否有未发送消息,这种与第二种情况一致,设好FIN后关闭angle算法。接下来,会设置最大等待时间l_linger,然后进程开始睡眠,直到确认对方接收到消息,将控制权交还给用户进程。
总结一下就是:调用close时,可能导致发送RST复位关闭连接,例如有未读消息、打开so_linger但l_linger却为0、关闭监听句柄时半打开的连接。更多时会导致发FIN来四次握手关闭连接,但打开so_linger可能导致close阻塞等待着对方的ACK表明收到了消息。
本文转自:小组15级成员--杜肖孟
原文地址:http://blog.csdn.net/tanswer_/article/details/78422879
<?php //在子类或类内部用“::”调用本类或父类时,不是静态调用方法,而是范围解析操作符。 class ParentClass { public static $my_static = 'parent var '; public function test() { self::who(); // 输出 'parent' 是范围解析,不是静态调用 $this->who(); // 输出 'child' static::who(); // 输出 'child' 延迟静态绑定 是范围解析,不是静态调用 } public function who() { echo 'parent<br>'; } }…
组织:中国互动出版网(http://www.china-pub.com/) RFC文档中文翻译计划(http://www.china-pub.com/compters/emook/aboutemook.htm) E-mail:ouyang@china-pub.com 译者:( ) 译文发布时间:2001-12-28 版权:本中文翻译文档版权归中国互动出版网所有。可以用于非商业用途自由转载,但必须保留 本文档的翻译及版权信息。 Network Working Group T. Socolofsky Request for Comments: 1180 C. Kale Spider Systems Limited January 1991 TCP/IP指南 (RFC1180——A TCP/IP Tutorial) 本备忘录的状态 这本 RFC 是 TCP/IP 协议的指南, 重点介绍通过一个路由 器从来源主机提交一个 IP 数据包到目的地主机的步骤。 它不指定一个因特网标准。 目录…
近期评论