然怎么也zb.com登不上上wwW3bb00com页面了,是不是3bb00网络的故障原因

由于您的浏览器禁用了javascript,无法正常使用本网站功能,
其它关键字
作 者 推 文
[收藏此章节] [下载]&&
  “愚蠢!无知!”斯内普吼道。    他不愿意看到哈利牺牲自己,但是又没有其他的好办法,只能用怒骂来表达自己的心情。    “西弗,我们还有时间,别着急,找到伏地魔的其他魂器然后销毁,这才是我们要做的事。或许我们在这期间可以找到让哈利不死的办法,不是吗?”邓布利多试图安抚着斯内普,但是连他自己也没有把握让哈利活下来。    办公桌上的银器还在旋转喷射着雾气,哈利和斯内普都没有反驳,或许他们心里都期望着真的会有奇迹发生,让哈利能够活下来。    “那么,萧先生,既然你是西弗信任的人,那么希望我们能合作愉快。”邓布利多像是才想起萧权的存在,笑容满面的对萧权伸出手。    “那个挂坠盒,要怎么销毁?”萧权并没有握住邓布利多的手,对于他来说斯内普才是他交易的对象,所以他和邓布利多之间不存在任何的合作。    “哦,我差点忘了,看我这记性。”邓布利多回到他的办公桌后,将手上的挂坠盒郑重的放到桌上,裸、露出来的一只手上有着烧伤的痕迹,颜色漆黑,手掌干瘪,而且萧权感觉到有什么在里面流动着。    感受到萧权的目光,邓布利多坦然的将干瘪的手露出来,笑着道:“这个是我销毁伏地魔七分之一灵魂的代价。”又从抽屉里拿出一枚戒指放在桌上。“马沃罗的戒指,它上面还有一个可怕的诅咒,我太大意了。也幸亏了西弗勒斯及时的给予了我治疗,让我得以还有一年的时间存活,而不是当场死亡。”邓布利多的神情一点也看不出这是一个已经时日不多的人。    哈利听到这个消息猛的瞪大了眼,邓布利多教授是他最敬爱的人,他不敢想象这个他最重要的老人会只有一年的寿命。    “哈利,我已经活的够长了,并不是所有人都像伏地魔那样渴望长生不死。”邓布利多摸了摸哈利的那头黑色短发,慈爱的说道。    “但是……教授……我不想看到您像小天狼星那样,如果,如果我可以更强大就可以保护你们。”哈利抽噎着道,他的朋友亲人一个个在他面前死去,或多或少都有他的原因,如果他可以有更强大的力量,那么就不会有人死。    邓布利多摇摇头,拍拍他的背脊说道:“很多事情不是能力够强大就能改变一切的,如果只想着追求力量,到最后可能会迷失方向,走向歧途。哈利,小天狼星的死不是你的错,我的死也不是你的错,你没有必要自责,每一个人都有他们要走的路,我们不能左右。”    “教授……”哈利的眼泪终于是忍不住流了下来,说到底他还只是个孩子,亲眼看着身边的朋友亲人受伤或者死去,内心早已经濒临崩溃。    邓布利多将哈利抱在怀里安抚着,救世主第一次将压抑的内心全部宣泄出来。所有人都认为他是救世主,所以拯救世界是他理所应当的事,没有人知道他内心的压力。就算是罗恩和赫敏,哈利也不曾述说过自己的内心。    斯内普冷哼一声别过脸不看哈利的蠢样,校长室里只有凤凰福克斯轻声的鸣叫和哈利轻微的抽噎声。    幸好哈利还知道这里还有其他人在,没有太过失态,趴在邓布利多怀里哭了几分钟就强迫自己止住哭泣,擦干眼泪,规规矩矩的站好。    邓布利多给了哈利一个鼓励的眼神,重新开口道:“马沃罗的戒指就是伏地魔的魂器之一,虽然它的力量很强大,但是我最终还是消灭了其中的伏地魔的灵魂碎片。而这要多亏于我们伟大的格兰芬多宝剑。”    邓布利多从墙上取下镶嵌着红宝石的格兰芬多宝剑,正是这把剑在哈利二年级时曾经帮助他杀死了蛇怪,所以哈利对它并不陌生。    而萧权看到格兰芬多宝剑的第一眼就是这是一把好剑,虽然他对武器没有什么研究,但是这把闪烁着正义之光的宝剑会让每一个看见过他的人忍不住赞叹它的美丽在,当然最重要的是这把宝剑不止锋利还含有剧毒。    “哈利,还记得你曾经用格兰芬多宝剑杀死了蛇怪吗?宝剑浸透了蛇怪的毒液,蛇怪的毒液正是能摧毁魂器的一种物质。我想我们可以再试一次以证明它的功效。”邓布利多双手握住宝剑,对着办公桌上斯莱特林挂坠盒劈了下去。    除了硬物碎裂开的声音,什么都没有发生,所有人一起凑过去,只见挂坠盒碎成了两半,除此之外没有任何事情发生。但是几人都不敢松懈,邓布利多用剑尖挑开挂坠盒的碎片,一张牛皮纸露了出来。    “看来我们似乎被骗了。”萧权一眼看清了纸上的字。    邓布利多看了他一眼,放下宝剑拿过那张纸念道:“致黑魔王:我知道,你读到这封信时,我早已经死了,但我想让你知道,是我,发现了你的秘密,我拿走了真的魂器,并将尽快销毁,我以死为代价,希望当你遇到敌手时,你会是个血肉之躯的凡人,R.A.B。”    “看来有人先我们一步拿走了挂坠盒,并且这是个非常聪明的人,不仅破解了伏地魔的陷阱还成功换成了一个假的挂坠盒。不过幸运的是这张字条的年代已经有些久了,或许真的挂坠盒已经被销毁了也不一定。”邓布利多微笑着开玩笑似的道。    “没有证据显示真的挂坠盒已经被销毁了,如果不能真正的确定,将会成为最大的祸患。”萧权的话让哈利的心又一次提到了嗓子眼。    “当然我们可以等到黑魔王被打败然后再一次复活时验证这个问题的答案,但是恐怕你的时间已经不够了,阿不思,霍格沃茨可不会再有一个阿不思·邓布利多校长来保护他们。”斯内普的眼神永远都是那么空洞,冷漠,就算是关心的话在他口中也变成了讽刺。    但是邓布利多并不在意,而是将格兰芬多宝剑插回原处,然后正色道:“只是开了个玩笑而已,就算我死了,西弗你也会尽心保护学校的学生的不是吗?”    不过邓布利多的话换来的只是斯内普的一声冷笑。    “只有R.A.B这几个字母确实不好推敲出是谁拿走了挂坠盒,那么,这件事就交给我来查。西弗和哈利……还有萧先生,你们有更重要的事做,我一个人无法找到所有的魂器,所以如果有什么线索,请告诉我好吗?另外,西弗,我们都知道伏地魔派德拉科·马尔福来杀我,如果他失败了,黑魔王一定会让你继续他的任务。不管有什么要求,答应他们,你的身份决不能被发现。”    说完邓布利多像是想起了什么,魔杖一挥,一叠蟑螂堆出现在办公桌上,密密麻麻的黑色甲壳型的蟑螂看的人有些起鸡皮疙瘩。虽然不是真的蟑螂,但是看起来就令人犯恶心。    “哦,不了,谢谢教授,我最近牙不怎么好,吃不了甜食。”哈利第一个摆着手拒绝。    “这可不是个好消息,哈利,你或许该吃点健齿魔药怎么样?西弗的魔药虽然口感不怎么好,但是可是异常见效呢。”邓布利多状似苦恼的捏着长长的胡子想了会,然后从一个小柜里拿出一小瓶魔药递给哈利。    该不会那一柜子都是健齿魔药吧!哈利忍不住想到,然后礼貌的拒绝道:“庞弗雷夫人已经给了我药。”    “那好吧,西弗,要来一点吗?”邓布利多又将盘子递到斯内普面前。    当然我们的毒舌教授是绝不会吃这种甜的发腻又根本激不起食欲的东西的。直接回给他一声冷哼根本没有伸手的意思。    “恩,我忘了西弗你是不吃甜食的了,怎么样,萧先生,要来一点吗?味道可不错哦。”邓布利多给自己找了个台阶,然后递给萧权一个还在扭动身躯的蟑螂糖。    “很奇怪的东西。”萧权歪着头看了邓布利多手里的糖几眼,最后接过来放进嘴里面无表情的三两下吞下肚,然后说道。“不过,还不错。”    僵尸对于除了鲜血之外的东西一般是没有什么感觉的,就算吃进去也是味同嚼蜡,不过这种会动会爬的新奇糖果难得的引起了萧权的兴趣。    于是萧权又伸手拿过一个放进嘴里,并不用牙齿咀嚼,而是先感受着糖果在嘴里活动的感觉,然后再一口咬下去。这样的追逐感让他有一种是在追逐活的猎物的感觉。    邓布利多笑眯眯的将一大盘蟑螂堆放进萧权的怀中,然后斯内普和哈利同时用一种很纠结的目光看着吃的津津有味的萧权。  
插入书签 
作者有话要说:还差3000到3万字
啊啊啊啊啊
我要崩溃了啊
看在人家这么努力的份上你们忍心不给评不给收吗?
不给就打滚给你们看
不给就给蟑螂堆你们吃(阴笑)
该作者现在暂无推文
支持手机扫描二维码阅读
wap读点击:
晋江APP→右上角人头→右上角小框
↑返回顶部
第9章 HP(八)
作 者 推 文
更多动态>>
地雷(100点)
手榴弹(地雷×5)
火箭炮(地雷×10)
浅水炸弹(地雷×50)
深水鱼雷(地雷×100)
个深水鱼雷(自行填写数量)
作者加精评论
本文相关话题
以上显示的是最新的二十条评论,要看本章所有评论,&figure&&img src=&https://pic1.zhimg.com/v2-014e6d5bb_b.jpg& data-rawwidth=&1920& data-rawheight=&1080& class=&origin_image zh-lightbox-thumb& width=&1920& data-original=&https://pic1.zhimg.com/v2-014e6d5bb_r.jpg&&&/figure&&h2&&b&为何需要内网穿透?&/b&&/h2&&p&&a href=&https://link.zhihu.com/?target=http%3A//www.ai4coder.cn/public/pages/%25E6%25B7%25B1%25E5%25BA%25A6%25E5%25AD%25A6%25E4%25B9%25A0%25E7%258E%25AF%25E5%25A2%%2590%25AD%25E5%25BB%25BA.html%23disqus_thread& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&配置好用于深度学习的GPU机器后&/a&,总是困扰我的是台式机放在家里,而我平时在公司想要使用GPU就比较困难; 最初采用的teamviewer的方式连接到家里的台式机,但是坑的是公司的网速实在不给力,加上我也只是在web端使用jupyter, 没必要传输整个桌面的内容;&/p&&p&Google搜索发现&a href=&https://link.zhihu.com/?target=https%3A//ngrok.com/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Ngrok&/a&就是我需要的内容穿透工具,完美解决内网访问的问题;&/p&&p&&br&&/p&&figure&&img src=&https://pic3.zhimg.com/v2-21dddf26d6c9d0e455b3d540fde1f8f2_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&1200& data-rawheight=&750& class=&origin_image zh-lightbox-thumb& width=&1200& data-original=&https://pic3.zhimg.com/v2-21dddf26d6c9d0e455b3d540fde1f8f2_r.jpg&&&/figure&&h2&&b&准备工作&/b&&/h2&&p&需要实现内网穿透,需要以下的内容:&/p&&ol&&li&公网服务器,我选择的阿里云基础版的服务器;&/li&&li&Ngrok1.7的版本(&b&注意:ngrok2.x的版本不再开源&/b&);&/li&&li&运行web服务的内网台式机(树莓派等都可以);&/li&&li&一级域名,可在阿里上购买;&/li&&/ol&&h2&&b&软件安装&/b&&/h2&&h2&安装gcc和golang等&/h2&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&sudo yum install gcc golang wget -y
&/code&&/pre&&/div&&h2&下载ngrok1.7&/h2&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&cd /usr/local/src
wget https://github.com/inconshreveable/ngrok/archive/1.7.1.tar.gz
tar -xf 1.7.1.tar.gz && cd ngrok-1.7.1
&/code&&/pre&&/div&&h2&生成证书&/h2&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&export NGROK_DOMAIN=&example_domain.com&
openssl genrsa -out rootCA.key 2048
openssl req -x509 -new -nodes -key rootCA.key -subj &/CN=$NGROK_DOMAIN& -days 5000 -out rootCA.pem
openssl genrsa -out device.key 2048
openssl req -new -key device.key -subj &/CN=$NGROK_DOMAIN& -out device.csr
openssl x509 -req -in device.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out device.crt -days 5000
&/code&&/pre&&/div&&h2&拷贝证书&/h2&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&cp rootCA.pem assets/client/tls/ngrokroot.crt
cp device.crt assets/server/tls/snakeoil.crt
cp device.key assets/server/tls/snakeoil.key
&/code&&/pre&&/div&&h2&生成服务端&/h2&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&GOOS=linux GOARCH=amd64
make release-server
&/code&&/pre&&/div&&h2&启动服务端ngrok&/h2&&p&在目录/usr/local/src/ngrok下运行:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&./bin/ngrokd -tlsKey=&assets/server/tls/snakeoil.key& -tlsCrt=&assets/server/tls/snakeoil.crt& -domain=&$NGROK_DOMAIN&
-httpAddr=&:8081& -httpsAddr=&:8082& -tunnelAddr=&:8083&
&/code&&/pre&&/div&&h2&生成客户端ngrok&/h2&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&GOOS=linux GOARCH=amd64 make release-client #如果是windows的话,修改GOOS=windows
&/code&&/pre&&/div&&h2&新建ngrok.cfg&/h2&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&server_addr: &example_domain:8083&
trust_host_root_certs: false
subdomain: &http&
http: &80&
remote_port: 8084
&/code&&/pre&&/div&&h2&创建启动ngrok-client脚本&/h2&&h2&使用以下命令新建/usr/bin/ngrok-start&/h2&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&sudo touch /usr/bin/ngrok-start
&/code&&/pre&&/div&&h2&vim修改ngrok-start&/h2&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&#!/bin/bash
check_ps=$(ps -ej | grep ngrok | grep -v ngrok-ali)
if [[ $? == 0 ]]; then
echo &ngrok client runnning.&
ngrok -config=/home/yourname/ngrok.cfg start http ssh # yourname换成你的主目录名
echo $check_ps
&/code&&/pre&&/div&&h2&修改ngrok-start的权限&/h2&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&sudo chmod 755 /usr/bin/ngrok-start
&/code&&/pre&&/div&&h2&在crontab添加任务(crontab -e)&/h2&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&# 每分钟检测ngrok client是否运行?
* * * * * /usr/bin/ngrok-ali
&/code&&/pre&&/div&&h2&&b&结语&/b&&/h2&&p&Ngrok能够完美解决内网穿透的问题,访问内网的电脑的效果也不错;&/p&&p&也可以访问&a href=&https://link.zhihu.com/?target=http%3A//www.deyuhua.me& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&我的主页&/a&,查看更多文章。&/p&
为何需要内网穿透?,总是困扰我的是台式机放在家里,而我平时在公司想要使用GPU就比较困难; 最初采用的teamviewer的方式连接到家里的台式机,但是坑的是公司的网速实在不给力,加上我也只是在web端使用jupyter, 没必要传输…
如果你习惯看英文文档,强烈建议你看“The TCP IP Guide” &a href=&//link.zhihu.com/?target=http%3A//www.tcpipguide.com/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Welcome to The TCP/IP Guide!&/a&&br&个人觉得秒杀目前一切书籍,而且非常好懂,读来一点不费劲,除了感觉有点罗嗦。
如果你习惯看英文文档,强烈建议你看“The TCP IP Guide”
个人觉得秒杀目前一切书籍,而且非常好懂,读来一点不费劲,除了感觉有点罗嗦。
&p&搞清这15个问题,那你就精通了TCP!&/p&&p& 网络协议那么多,为什么面试喜欢问TCP?原因无外乎两个:&/p&&p&1、TCP协议直接与进程打交道,写网络程序要用;&/p&&p&2、TCP协议设计十分精巧,在一个不可靠的IP网络上实现了可靠传输,因为精巧,掌握TCP的原理自然也有难度,对它掌握如何,很能反映面试者的基础水平。闲言少叙,看看这几个问题你能不能答出来! &/p&&p&1、A进程通过TCP向另一台机器上的B进程发送了一个字符串“hello”,TCP返回对方成功接收的确认信息,请问,现在进程A是否可以肯定地说进程B收到了它发送的字符串?&/p&&div class=&highlight&&&pre&&code class=&language-text&&答案:不能!举反例,进程B所在机器的TCP收到进程A发送的“hello”信息后,告诉进程A发送成功,但有可能没有立即将数据交给进程B,而是放在自己的缓冲区中,等待进程B读取,如果机器此时突然掉电,缓冲区中的信息将丢失,进程B将不可能收到“hello”字符串。
&/code&&/pre&&/div&&p&2、有什么办法来尽量避免上述情况的发生呢?&/p&&div class=&highlight&&&pre&&code class=&language-text&&答案:将TCP报文段首部中的PSH标志置1,这样会让B端的TCP协议收到数据后尽快交给进程B,能不缓存尽量不要缓存。
&/code&&/pre&&/div&&p&3、我们知道通常TCP连接的建立需要3次握手,关闭需要4次握手,为什么关闭会多一次呢?&/p&&div class=&highlight&&&pre&&code class=&language-text&&答案:简单说,就是TCP允许半关闭状态的存在。当进程A向进程B发送FIN,B也向A发送确认后。此时此刻的状态就是半关闭状态,A发送的FIN就是告诉B:“我要发送的数据都发送完了”但B没有发送FIN给A,有可能代表B还有没发送完的数据,如果B也发送完数据了,B就发送FIN给进程A,进程A确认B发送的FIN,这时,双方都已经发送完了数据,连接就断开了,TCP回收相关资源。
&/code&&/pre&&/div&&p&4、假如服务器突然掉电重启,但客户端并不知情,请问此时二者之间的TCP连接处于什么状态?&/p&&div class=&highlight&&&pre&&code class=&language-text&&答案:处于半打开状态。就是客户端还觉得连接是正常的,服务器这边已经没有连接的任何信息了。
&/code&&/pre&&/div&&p&5、那么,假如此时客户端通过这个连接向服务器请求数据,服务器会怎么应对呢?&/p&&div class=&highlight&&&pre&&code class=&language-text&&答案:服务器收到客户端的请求会进行一次ARP查询,获得客户端MAC地址,然而由于已经丢失了所有连接信息,此时的服务器是一脸懵逼(就像喝了孟婆汤!),于是乎,它会发一个RST给客户端,表示:“哥们,我不认识你,想跟我说话请先发送SYN!”
&/code&&/pre&&/div&&p&6、假如客户端按照服务器的要求重新建立连接,却搞错了服务器的端口号,会发生什么情况呢?&/p&&div class=&highlight&&&pre&&code class=&language-text&&答案:有两种可能,一种是服务器端的TCP收到客户端请求,查看本机上是否有进程在监听相应的端口,如果有,就把请求交给这个进程,一般而言,这个进程不会接受这个连接的,于是它会发一个RST给客户端。还有一种可能是TCP没有找到哪个进程在监听相应的端口,于是TCP就会直接发一个RST给客户端,一般而言都会是这种情况。
&/code&&/pre&&/div&&p&7、假如现在有一个多进程服务器,服务器进程为A,接受一个连接后新建一个进程B来处理连接,再接受一个连接后又建一个进程C来处理这个连接,请问,进程ABC是否监听同样的端口?&/p&&div class=&highlight&&&pre&&code class=&language-text&&答案:是!
&/code&&/pre&&/div&&p&8、那TCP接收到发送给这个端口的报文段,怎么决定发给哪个进程呢?&/p&&div class=&highlight&&&pre&&code class=&language-text&&答案:首先,所有的SYN报文段都会发送给服务器进程A,其他的报文段依据&sourceIP:port,targetIP:port&这个四元组来决定发送给进程B还是进程C。
&/code&&/pre&&/div&&p&9、假如上面的服务器进程A收到一个连接请求,正在为这个请求创建处理进程的时候,又有新的连接请求进来了,TCP会怎么处理呢?&/p&&div class=&highlight&&&pre&&code class=&language-text&&答案:一般情况下,服务器进程A会给TCP一个指示,让TCP维护一个适当长度的连接队列,TCP与新连接请求完成三次握手后,就会把这个连接放入连接队列中,服务器进程A会在合适的时候来从这个队列中取连接。
&/code&&/pre&&/div&&p&10、这个连接对列是否会对服务器的并发处理能力产生影响呢?如果会,会有什么影响?&/p&&div class=&highlight&&&pre&&code class=&language-text&&答案:不会!二者没有必然关系。
&/code&&/pre&&/div&&p&11、MSS和MTU各是什么,二者是什么关系?&/p&&div class=&highlight&&&pre&&code class=&language-text&&答案:MSS是TCP最大报文段长度,就是TCP发送数据需要对数据分段时,最大的段的字节数。MTU是最大传输单元,通常由网卡的硬件特性规定,表示通过该网卡传输的数据单元最大的字节数。MSS要受同一台机器上的MTU限制。比如MTU为1500字节,那么MSS就只能是1460字节,这是因为1460字节的数据在通过网卡向外传输时,会加上20字节的ip头和20字节的tcp头。
&/code&&/pre&&/div&&p&12、假设机器A和B的MSS分别是,请问,A通过TCP向B发送数据时,是否可以发送长度为1600字节的数据段?&/p&&div class=&highlight&&&pre&&code class=&language-text&&答案:不可以,虽然发送1600字节的数据段没有突破B的MSS,但是突破了A自己的MSS。这样一来,当这1600字节的数据段通过A的网卡向B发送时,会被切分为2个IP片,每个为840字节,以保证不突破A的MTU,这显然降低了传输的效率,因为两个840字节中有着相同的IP头和TCP头。
&/code&&/pre&&/div&&p&13、机器A和B有一条TCP连接,假如A想尽快断开连接,应当怎么办?&/p&&div class=&highlight&&&pre&&code class=&language-text&&答案:A可以直接给B发送一个RST,就可以了,相当于告诉B,我关闭连接了,你看着办吧。这叫做异常关闭。
&/code&&/pre&&/div&&p&14、B的TCP收到A发来的RST,会怎么办?&/p&&div class=&highlight&&&pre&&code class=&language-text&&答案:B的TCP会告诉上层的进程,连接已经断开了,然后就会回收这条连接的资源,并不会发送任何确认信息给A。所谓你无情休怪我不义。
&/code&&/pre&&/div&&p&15、假设A正常断开与B的TCP连接,当收到B的FIN时,A发送ACK给B,是否就算完成了4次握手,连接已经成功断开?&/p&&div class=&highlight&&&pre&&code class=&language-text&&答案:不是,A的TCP会启动一个定时器,等待2MSL的时间,这主要是为了防止A的ACK没有成功传到B,让B以为自己的FIN没有送到A处,反复重传FIN的问题。2MSL的时间到时,如果A没有再次收到B的FIN,说明B成功收到A的ACK,A就可以安全地断开这个连接,若期间再次收到B的FIN,则A会重传ACK。
&/code&&/pre&&/div&
搞清这15个问题,那你就精通了TCP! 网络协议那么多,为什么面试喜欢问TCP?原因无外乎两个:1、TCP协议直接与进程打交道,写网络程序要用;2、TCP协议设计十分精巧,在一个不可靠的IP网络上实现了可靠传输,因为精巧,掌握TCP的原理自然也有难度,对它掌握…
&figure&&img src=&https://pic4.zhimg.com/aeea2b9be41ee15c69ffee38abcff204_b.jpg& data-rawwidth=&722& data-rawheight=&1080& class=&origin_image zh-lightbox-thumb& width=&722& data-original=&https://pic4.zhimg.com/aeea2b9be41ee15c69ffee38abcff204_r.jpg&&&/figure&TCP报文可以说是最常见的报文之一,但TCP具体的工作原理了解的人却不多,在这里展开来说一说这个TCP协议,了解比较深或者想要完整了解这个协议的朋友可以直接去查阅&a href=&http://link.zhihu.com/?target=https%3A//tools.ietf.org/html/rfc793& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&RFC793&/a&,本文只是尽量写一些TCP比较重要的功能及实现,远远达不到全面、准确这两点。&p&&b&简介&/b&&/p&&p&TCP = TRANSMISSION CONTROL PROTOCOL,即传输控制协议。&/p&&p&在网络中,TCP协议处于第四层,在物理层(线缆,光纤,无线信道等),数据链路层(交换层面segment),网络层(IP)这三个层面之上的一层协议。也就是说,在我们讨论TCP协议的时候,意味着我们的前提是IP可达,ping包可通的情况下。&/p&&p&那为什么要设计TCP协议呢?因为实际需求就在那里,好吧我来翻译这句话。&/p&&p&首先我们知道,需要给两台设备设计的通信有很多很多,比方说你要上传/下载文件,发送QQ消息,发送邮件等等,如果把这些协议都设计成三层,那么IP协议将会十分复杂且低效。所以我们新增了四层端口号这个概念,将网络拓展到了四层。这时候两种声音出现了,一种声音是可靠传输,但会损失一些性能;另一种声音是不需要可靠传输,要的是更低的延迟,更精简的包头。因为有这两种不同的需求,所以TCP和UDP两种协议便被设计并规范出来。可以说TCP是为了满足多样,可靠的传输而出现的产物。&/p&&p&&b&包头&/b&&/p&&p&当我们谈及网络协议时,最简单的方法就是看它的包头,如果能深刻的理解包头每个字节的作用,那么你也就真正的理解了这种网络协议。不多说,上图。&br&&/p&&figure&&img src=&https://pic1.zhimg.com/a323eb3f98fa37bf2de1a08_b.png& data-rawwidth=&1082& data-rawheight=&599& class=&origin_image zh-lightbox-thumb& width=&1082& data-original=&https://pic1.zhimg.com/a323eb3f98fa37bf2de1a08_r.jpg&&&/figure&&br&&p&前文已经说过,TCP协议设计出来的主要目的是为了满足多样、可靠这两种需求。图中的前三行,4个字段,共12个字节很好的解释了这一点。&/p&&p&Source Port & Destination Port:
16 bits*2&/p&&p&源端口和目的端口各占16 bits,也就是说我们可以拥有2^16 = 65536个端口号,也就是说我们可以开放这6万多个端口给一台设备提供不同的服务。&/p&&p&Sequence Number & Acknowledgment Number:
32 bits*2&/p&&br&&p&这两个字段各自占据了TCP包头4个字节的位置,其重要性可想而知,而且TCP的可靠传输主要是靠这两个字节来实现,具体它们是如何实现在工作这一小节去具体描述。再往下看。&/p&&p&Data Offset:
4 bits&/p&&p&因为TCP包头中有部分可选字段,所以我们需要一个指针来指示数据的开始的地方,Data Offset字段完成的就是这顶功能。有细心的同学会发现,它的最大值为2^4 = 16,而图中的TCP包头已经有24个字节了,这里要特殊说明的是,这里的1是代表1行,也就是4个字节的内容,我们可以表示的范围是(0 ~ 15)*4 = 0 ~ 60字节,而TCP最少占有20个字节,这就意味着我们最多有40个字节的可选字段可以使用。&/p&&p&Reserved:
6 bits&br&&/p&&p&这是保留字段,不用时设为0。或许当我们需要实现新的功能时,这6个bit可以提供相应的标识。目前后三个bit已经有用作标识,&a href=&http://link.zhihu.com/?target=https%3A//tools.ietf.org/html/rfc3540& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&NS&/a&、&a href=&http://link.zhihu.com/?target=https%3A//tools.ietf.org/html/rfc3168& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&CWR&/a&、&a href=&http://link.zhihu.com/?target=https%3A//tools.ietf.org/html/rfc3168& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&ECE&/a&,有兴趣的同学可以自己去看看相关RFC的规定。&/p&&p&Control Bits:
6 bits&br&&/p&&p&URG:
Urgent Pointer field significant&br&&/p&&p&确认是否有紧急指针,即第五行后面的Urgent Pointer字段。&/p&&p&ACK:
Acknowledgment field significant&br&&/p&&p&确认是否为ACK信息,除了初始的SYN包外,这个字段都应标为1。&/p&&p&PSH:
Push Function&br&&/p&&p&确认是否将数据推给上层协议,如果是1则推送,如果是0则先缓存下来。&/p&&p&RST:
Reset the connection&br&&/p&&p&确认是否重置连接,如果出现重大差错,会将该字段置为1。&/p&&p&SYN:
Synchronize sequence numbers&br&&/p&&p&确认是否为同步序列号,只有从端发出的第一个包才会将该该置为1.&/p&&p&FIN:
No more data from sender&br&&/p&&p&确认是否中断。如果发送方将信息发送完毕则将该字段置为1。&/p&&p&Window:
16 bits&br&&/p&&p&表示从确认号开始,本报文的源方可以接收的字节数,即源方接收窗口大小。这是个很有意思的机制,有机会再展开讨论一下。&br&&/p&&p&Checksum:
16 bits&br&&/p&&p&对整个的TCP报文段,包括TCP头部和TCP数据,以16位字进行计算所得。该字段主要确认在信道传输过程中,内容无差错。&br&&/p&&p&Urgent Pointer:
16 bits&br&&/p&&p&用作指针,指到紧急数据的结束位。主要用途是传输一些紧急数据,这里不展开说了。&/p&&p&Options & Padding&/p&&p&扩展字段,前文已经计算过,最长为40个字节,这里也不展开说了。&/p&&p&Data&/p&&p&数据,前面那么多包头的信息,传输的就是这数据,研究协议的时候,我们把他看作成一个整体就好,不用关心我们到底利用这个协议传输了什么内容。至于MTU长度,分片等内容也很重要,有时间再写吧。&/p&&p&&b&工作原理&/b&&/p&&p&因为不能把所有的IP协议都当作TCP协议来使用,所以我们规定,当检测到IP协议中PROTOCOL字段为6时,我们将IP字段后的协议视为TCP协议。也就是说,我们讨论的前提又加了一项,TCP协议被调用。&/p&&p&TCP的功能有很多很多,在这里选择介绍两项关注比较多的内容,连接建立/断开和流量控制。如果一起讨论其它功能,可以在评论区留言说明。&/p&&p&连接建立/断开&br&&/p&&p&一个正常的TCP连接从建立到分开,要完成三次握手四次挥手。先是建立,见图。&figure&&img src=&https://pic4.zhimg.com/e7f75f4d6d9d950bbd7ceb_b.png& data-rawwidth=&440& data-rawheight=&378& class=&origin_image zh-lightbox-thumb& width=&440& data-original=&https://pic4.zhimg.com/e7f75f4d6d9d950bbd7ceb_r.jpg&&&/figure&&/p&&ol&&li&客户端向服务器申请建立TCP连接,向服务器端发送一个SYN报文,作为第一次握手。客户端把这段连接的SYN设定为随机数A。&/li&&li&服务器端收到SYN报文后,会给客户端发送一个报文。报文中ACK的确认码为A+1,同时发送另一个SYN为随机序号B。&/li&&li&此时,客户端收到ACK为A+1的报文,将之与发送的SYN包进行比对,如果满足+1的关系,则在客户端判断连接已建立。并给服务器发送确认数据包,SYN为A+1,表明已收到上一报文,ACK为B+1,通知服务器进入连接状态。&/li&&/ol&&p&至此,TCP连接建立完毕,可以正常传输数据了。再是连接终结,即四次挥手,还是看图。&figure&&img src=&https://pic4.zhimg.com/283ab7bccdc_b.png& data-rawwidth=&424& data-rawheight=&398& class=&origin_image zh-lightbox-thumb& width=&424& data-original=&https://pic4.zhimg.com/283ab7bccdc_r.jpg&&&/figure&终结连接操作可由双方任意一方发起。本文以客户端发起为例。&/p&&ol&&li&客户端向服务器端发送一个FIN报文,作为第一次挥手。通知服务器,我已经没有数据还要发送。但不确认服务器是否扔有数据返回,所以连接仍是建立状态。&/li&&li&服务器收到FIN报文,返回一个ACK报文,告诉客户端,我知道你已经没有东西要发送了,但我还要再确认一下我是不是还有东西要给你。&/li&&li&服务器判断自己也没有报文需要发送给客户端,发送FIN消息,告诉客户端,好了,这下我也没有东西要给你了,你可以终结连接了。此时服务器不确认客户端是否收到信息,继续保持连接。&/li&&li&客户机收到ACK和FIN消息后,得知服务器已经知道自己要终结,并且无更新内容,便给服务器发送一个ACK说我知道了,你也终结吧,客户机便终结连接。服务器在收到最后一条ACK后,也终结连接。&br&&/li&&/ol&&p&至此,四次挥手操作完成,连接终结。&/p&&p&拥塞控制&/p&&br&&p&要注意的是,拥塞控制和流量控制不是一回事,今天要说的是拥塞控制,流量控制有机会再聊。拥塞控制是TCP协议设计中一个很棒的特性,这个特性让TCP协议在网络传输中合理的利用带宽,使速度最大化。TCP中的拥塞控制用到以下几种技术,慢启动、拥塞避免、快速重传和快速恢复技术。&/p&&p&慢启动技术。如果连接建立好,一上来就给对端发大量的报文,可能无法到达,并造成网络链路的拥塞。慢启动技术是开始会发很小的报文给对端,收到对端的ACK判断可达后,会加倍报文量发送同时等待,如果收到对端的ACK则继续加倍,如果等待超时且没有收到ACK则意味着报文过大,超过链路负荷,开始发送原有报文+1大小的报文,如此反复。以达到最大利用带宽。&/p&&p&可以说,慢启动是拥塞控制技术的核心。但如果在传输中遇到了链路不稳定,TCP则会让传输速度降至谷底,将窗口设为1,继续慢启动。这样,一个小小的干扰就让速度损失这么多,并且浪费了带宽,IT人肯定是不同意的,所以就有了后面几种机制。这么多的技术,其目的只有一个,尽可能大的利用带宽!抓住这一点再对后面的技术产生和原理进行理解,将事半功倍。这里就不再展开继续说明了。&/p&&p&总之,这次写了不少东西,也挖了不少坑,具体要不要填,填哪些坑,希望和朋友们一起探讨,欢迎大家留言。&/p&&p&最后,贴一下TCP完整的逻辑判断及状态机流程图,如果能看懂这张图以及上面的报文图。可以说你已经对TCP有了一个较深的理解了。&br&&/p&&figure&&img src=&https://pic4.zhimg.com/dca73afb5cedd8af85ae7_b.png& data-rawwidth=&1176& data-rawheight=&1273& class=&origin_image zh-lightbox-thumb& width=&1176& data-original=&https://pic4.zhimg.com/dca73afb5cedd8af85ae7_r.jpg&&&/figure&&p&&b&参考&/b&&/p&&p&本文部分内容,引用自Wikipedia和相关RFC,有兴趣深入了解的朋友也可以自行查看。&/p&&p&&a href=&http://link.zhihu.com/?target=https%3A//en.wikipedia.org/wiki/Transmission_Control_Protocol& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&TCP维基百科&/a&&br&&/p&&p&&a href=&http://link.zhihu.com/?target=https%3A//tools.ietf.org/html/rfc793& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&TRANSMISSION CONTROL PROTOCOL&/a&&br&&/p&&p&&a href=&http://link.zhihu.com/?target=https%3A//tools.ietf.org/html/rfc1323& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&TCP Extensions for High Performance&/a&&/p&
TCP报文可以说是最常见的报文之一,但TCP具体的工作原理了解的人却不多,在这里展开来说一说这个TCP协议,了解比较深或者想要完整了解这个协议的朋友可以直接去查阅,本文只是尽量写一些TCP比较重要的功能及实现,远远达不到全面、准确这两点。简介TC…
简短版本:&br&&br&TCP特性使得每个TCP连接可以得到均等的带宽。在多用户环境下,一个用户拥有越多TCP连接,获得的带宽越大。&br&&br&具体来说:&br&&br&这个涉及到了TCP的拥塞控制。&br&&br&我们先看一下单TCP连接的拥塞控制。&br&&br&这是一个TCP连接的发送窗口。&br&&figure&&img src=&https://pic3.zhimg.com/ac38d18e3cd9c7941bbd753fe37bbbba_b.jpg& data-rawwidth=&434& data-rawheight=&309& class=&origin_image zh-lightbox-thumb& width=&434& data-original=&https://pic3.zhimg.com/ac38d18e3cd9c7941bbd753fe37bbbba_r.jpg&&&/figure&&br&绿色部分为发送者已发送,且接收者已确认(ACKed)。&br&黄色部分为发送者已发送,但接收者尚未确认(&in-flight&)。&br&蓝色部分为可用但尚未发送。&br&灰色部分为不可用。&br&&br&所以在RTT(round-trip time,来回通讯延迟)不变的情况下,cwnd这个变量基本决定传输速率。&br&&figure&&img src=&https://pic3.zhimg.com/382de3ccf7e_b.jpg& data-rawwidth=&401& data-rawheight=&105& class=&content_image& width=&401&&&/figure&发送者总会试图找到不丢包情况下的最大速率。按照TCP协议,在传输开始之后,每接收到一个确认(ACK)就会把cwnd这个变量增大一倍。所以TCP连接开始之后应该是这个样子。&br&&figure&&img src=&https://pic2.zhimg.com/d6eceab08d6e7e33b62f8d_b.jpg& data-rawwidth=&519& data-rawheight=&508& class=&origin_image zh-lightbox-thumb& width=&519& data-original=&https://pic2.zhimg.com/d6eceab08d6e7e33b62f8d_r.jpg&&&/figure&刚开始的时候传输速率应该是指数被增长的,直到丢包发生。丢包会有两种情况:&br&1.当接收者发送给发送者的ACK丢失了,这时会触发超时(timeout)。&br&2.当发送者发送给接收者的数据包丢失了,发送者会收到接收者发来的重复ACK,如果发送者收到了3个重复的ACK,也会认为发生了丢包。&br&&br&具体对这两种情况采取的措施略有不同,但粗略来说,变量cwnd会被减半,也就是说传输速率减半。然后cwnd会再次增大,直到下次丢包发生。所以忽略最开始,TCP的吞吐量应该是这样。&br&&figure&&img src=&https://pic2.zhimg.com/931df6ccfd37c82594b21_b.jpg& data-rawwidth=&663& data-rawheight=&329& class=&origin_image zh-lightbox-thumb& width=&663& data-original=&https://pic2.zhimg.com/931df6ccfd37c82594b21_r.jpg&&&/figure&&br&好,那么现在我们来看多TCP连接的拥塞控制。&br&我们假设有两条同样的TCP连接。在他们的连接中间有一个共用的瓶颈路由器,带宽为R。&br&&figure&&img src=&https://pic3.zhimg.com/91b57eaefef2_b.jpg& data-rawwidth=&807& data-rawheight=&410& class=&origin_image zh-lightbox-thumb& width=&807& data-original=&https://pic3.zhimg.com/91b57eaefef2_r.jpg&&&/figure&假设这两条连接都需要传输足够大量的数据,那么不论他们谁先开始传输,最后一定会均分带宽。&br&&figure&&img src=&https://pic4.zhimg.com/6dab723d3bbdffb03c748a1b69bba2df_b.jpg& data-rawwidth=&853& data-rawheight=&489& class=&origin_image zh-lightbox-thumb& width=&853& data-original=&https://pic4.zhimg.com/6dab723d3bbdffb03c748a1b69bba2df_r.jpg&&&/figure&因为如果总传输速率低于R的时候就会不断增大传输速率,某个连接在增大传输速率的时候发生丢包就会减半传输速率,最后趋于平衡。&br&&br&所以k条经过同一节点TCP连接会平分带宽R,每条连接得到带宽R/k。&br&&br&正因为如此,不论是以前的net vampire,还是现在的迅雷都采取增加并发连接数的方法来加快下载速度。&br&&br&references:&br&&ul&&li&James F. Kurose, Keith W. Ross: &a href=&//link.zhihu.com/?target=http%3A//www.pearsonhighered.com/pearsonhigheredus/educator/product/products_detail.page%3Fisbn%3D1& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Computer Networking: A Top-Down Approach&/a&, 6e&/li&&/ul&
简短版本: TCP特性使得每个TCP连接可以得到均等的带宽。在多用户环境下,一个用户拥有越多TCP连接,获得的带宽越大。 具体来说: 这个涉及到了TCP的拥塞控制。 我们先看一下单TCP连接的拥塞控制。 这是一个TCP连接的发送窗口。 绿色部分为发送者已发送,且…
&figure&&img src=&https://pic3.zhimg.com/v2-c325e5b5caeec8d13a325b_b.jpg& data-rawwidth=&777& data-rawheight=&290& class=&origin_image zh-lightbox-thumb& width=&777& data-original=&https://pic3.zhimg.com/v2-c325e5b5caeec8d13a325b_r.jpg&&&/figure&&p&NAT是什么?&/p&&p&NAT(Network Address Translation,网络地址转换)是1994年提出的。当在专用网内部的一些主机本来已经分配到了本地IP地址(即仅在本专用网内使用的专用地址),但现在又想和因特网上的主机通信(并不需要加密)时,可使用NAT方法。&/p&&p&这种方法需要在专用网连接到因特网的路由器上安装NAT软件。装有NAT软件的路由器叫做NAT路由器,它至少有一个有效的外部全球IP地址。这样,所有使用本地地址的主机在和外界通信时,都要在NAT路由器上将其本地地址转换成全球IP地址,才能和因特网连接。&/p&&p&NAT的功能:&/p&&p&NAT不仅能解决了lP地址不足的问题,而且还能够有效地避免来自网络外部的攻击,隐藏并保护网络内部的计算机。把内网的私有地址,转化成外网的公有地址。使得内部网络上的(被设置为私有IP地址的)主机可以访问Internet。&/p&&p&1.宽带分享:这是 NAT 主机的最大功能。&/p&&p&2.安全防护:NAT 之内的 PC 联机到 Internet 上面时,他所显示的 IP 是 NAT 主机的公共 IP,所以 Client 端的 PC 当然就具有一定程度的安全了,外界在进行 portscan(端口扫描) 的时候,就侦测不到源Client 端的 PC 。&/p&&p&NAT分为哪几种?&/p&&p&NAT可以分为Basic NAT和PAT:&/p&&p&- Basic NAT只转化IP,不映射端口。&/p&&p&- PAT除了转化IP,还做端口映射,可以用于多个内部地址映射到少量(甚至一个)外部地址。&/p&&p&NAT还可以分为静态NAT和动态NAT:&/p&&p&- 静态NAT,将内部网络中的每个主机都永久映射成外部网络中的某个合法的地址,多用于服务器。&/p&&p&- 动态NAT,则是在外部网络中定义了一个或多个合法地址,采用动态分配的方法映射到内部网络。&/p&&p&为什么需要有NAT?&/p&&p&NAT的主要作用,是解决IP地址数量紧缺。当大量的内部主机只能使用少量的合法的外部地址,就可以使用NAT把内部地址转化成外部地址。&/p&&p&NAT还可以防止外部主机攻击内部主机(或服务器)。&/p&&p&怎样映射?&/p&&p&如何将大量的内部地址,映射成少量的外部地址?&/p&&p&对于第四层是TCP或UDP的数据包,NAT通过更改源端口号,来实现多对少的映射。&/p&&p&例如:内部IP1~IP4,4个地址映射成外部一个地址IP5。&/p&&p&(IP1,Port1)映射成(IP5,Port1)&/p&&p&(IP2,Port1)映射成(IP5,Port2)&/p&&p&(IP3,Port2)映射成(IP5,Port3)&/p&&p&(IP4,Port2)映射成(IP5,Port4)&/p&&p&对于ICMP包,NAT通过更改ICMP的ID,来实现多对少的映射。&/p&&p&TCP或UDP的端口,原本是用来做什么的?&/p&&p&端口号是用来连接上层程序的。例如,端口号23,对应了Telnet;端口号80,对应了Http等等。&/p&&p&因此,在本动画中,当R1转化H1发送给Server的TCP包的时候,不能转化目的地端口。Server正是通过端口号23,才知道把收到的TCP交给Telnet处理。&/p&&p&NAT有什么弊端?&/p&&p&在一个具有NAT功能的路由器下的主机并没有建立真正的端对端连接,并且不能参与一些因特网协议。一些需要初始化从外部网络建立的TCP连接,和使用无状态协议(比如UDP)的服务将被中断。除非NAT路由器作一些具体的努力,否则送来的数据包将不能到达正确的目的地址。(一些协议有时可以在应用层网关的辅助下,在参与NAT的主机之间容纳一个NAT的实例,比如FTP。)NAT也会使安全协议变的复杂。&/p&&p&NAT局限性&/p&&p&(1)NAT违反了IP地址结构模型的设计原则。IP地址结构模型的基础是每个IP地址均标识了一个网络的连接。Internet的软件设计就是建立在这个前提之上,而NAT使得有很多主机可能在使用相同的地址,如10.0.0.1。&/p&&p&(2)NAT使得IP协议从面向无连接变成面向连接。NAT必须维护专用IP地址与公用IP地址以及端口号的映射关系。在TCP/IP协议体系中,如果一个路由器出现故障,不会影响到TCP协议的执行。因为只要几秒收不到应答,发送进程就会进入超时重传处理。而当存在NAT时,最初设计的TCP/IP协议过程将发生变化,Internet可能变得非常脆弱。&/p&&p&(3)NAT违反了基本的网络分层结构模型的设计原则。因为在传统的网络分层结构模型中,第N层是不能修改第N+1层的报头内容的。NAT破坏了这种各层独立的原则。&/p&&p&(4)有些应用是将IP地址插入到正文的内容中,例如标准的FTP协议与IP Phone协议H.323。如果NAT与这一类协议一起工作,那么NAT协议一定要做适当地修正。同时,网络的传输层也可能使用TCP与UDP协议之外的其他协议,那么NAT协议必须知道并且做相应的修改。由于NAT的存在,使得P2P应用实现出现困难,因为P2P的文件共享与语音共享都是建立在IP协议的基础上的。&/p&&p&(5)NAT同时存在对高层协议和安全性的影响问题。RFC对NAT存在的问题进行了讨论。NAT的反对者认为这种临时性的缓解IP地址短缺的方案推迟了Ipv6迁移的进程,而并没有解决深层次的问题,他们认为是不可取的。&/p&&p&名词解释:&/p&&p&NAT网络地址转换(正常数据转发时,IP头部的源和目的地址以及端口号是不会被更改的,而使用了NAT技术后,它将更改头部内容以达实现隐藏内外部主机真实地址、多台主机共享少量IP访问内外部网络、解决IP地址空间重叠、服务器负载均衡等功能)&/p&&p&PAT端口地址转换,又叫网络地址端口转换(NAPT)或NAT的端口复用(用IP地址+端口号来对应和区别各个数据流进行网络地址转换,以达到多内部主机通过一个或少量合法IP地址来访问外部网络)&/p&&p&Inside内部&/p&&p&Outside外部&/p&&p&Inside local内部本地地址(内部主机的实际地址,一般为私有地址)&/p&&p&Inside global内部全局地址(内部主机经NAT转换后去往外部的地址,是ISP分配的合法IP地址)&/p&&p&Outside local外部本地地址(外部主机由NAT设备转换后的地址,一般为私有地址,内部主机访问该外部主机时,认为它是一个内部的主机而非外部主机)&/p&&p&Outside global 外部全局地址(外部主机的真实地址,互联网上的合法IP地址)&/p&&p&NAT超时:&/p&&p&没有使用PAT时则为24小时&/p&&p&使用PAT:&/p&&p&UDP超时值: 5分钟&/p&&p&DNS : 1分钟&/p&&p&TCP : 24小时&/p&&p&NAT的实现示范:&/p&&p&1,ip nat inside source&/p&&p&2,ip nat inside destination&/p&&p&都是内部地址转换,ip nat inside source&/p&&p&即是IL-&IG (由内部发起的流量)&/p&&p&ip nat inside destination&/p&&p&即是IG-&IL (由外部发起的流量)&/p&&p&撇开流量的发起方不说,达到的效果是一样的(都是IL与IG之间转换),即NAT Translation表的IL和IG项都一样。&/p&&p&但是对于ip nat inside destination需要注意:&/p&&p&①只有TCP流量才会转换,ping 流量是不会触发NAT的Destination转换的!&/p&&p&②nat pool 一定要设置type为 rotary!!&/p&&p&ip nat inside source举例&/p&&figure&&img src=&https://pic4.zhimg.com/v2-6ed695dd_b.jpg& data-rawwidth=&640& data-rawheight=&304& class=&origin_image zh-lightbox-thumb& width=&640& data-original=&https://pic4.zhimg.com/v2-6ed695dd_r.jpg&&&/figure&&br&&p&说明: ip nat inside / ip nat ouside -&/p&&p&假定ISP为网络1分配了IG地址段:100.0.0.0/28&/p&&p&配置:&/p&&p&GW1:&/p&&p&GW1(config)#int s0&/p&&p&GW1(config-if)#ip nat outside /定义外部接口&/p&&p&GW1(config-if)#int e0&/p&&p&GW1(config-if)#ip add 192.168.0.1 255.255.255.0&/p&&p&GW1(config-if)#ip nat inside /定义内部接口&/p&&p&GW1(config-if)#exit&/p&&p&GW1(config)#access-list 1 permit 192.168.0.0 0.0.0.255 /用ACL捕捉IL地址&/p&&p&GW1(config)#ip nat pool POOL_NAME 100.0.0.1 100.0.0.14 prefix-length 28 /定义IG地址池&/p&&p&GW1(config)#ip nat inside source list 1 pool POOL_NAME /将ACL1里指定的IG地址从名为POOL_NAME的地址池里动态顺序地取IG地址进行映射&/p&&p&ip nat inside destination 举例(服务器负载均衡)&/p&&p&当我们内部有几台提供相同服务的服务器时,我们可以用NAT来做到负载分担,它的分担方式是基于每次访问的,如下图,如果用NAT做了负载分担,我们把这三台服务器的IL映射为同一个IG,这时外部用户访问该IG地址时,NAT会进行&/p&&p&基于每次访问的负载分担。用户第一次访问时会定向到Server1,第二次则是Server2,第三次则是Server3,轮循完后又回到Server1,服务器依次轮流对外提供服务。&/p&&figure&&img src=&https://pic4.zhimg.com/v2-76d319b4cdc9e9fa1fe56_b.jpg& data-rawwidth=&693& data-rawheight=&378& class=&origin_image zh-lightbox-thumb& width=&693& data-original=&https://pic4.zhimg.com/v2-76d319b4cdc9e9fa1fe56_r.jpg&&&/figure&&br&&p&说明: ip nat inside / ip nat ouside -&/p&&p&配置:&/p&&p&GW1(config)#int s0&/p&&p&GW1(config-if)#ip nat outside /定义外部接口&/p&&p&GW1(config-if)#int e0&/p&&p&GW1(config-if)#ip add 192.168.0.1 255.255.255.0&/p&&p&GW1(config-if)#ip nat inside /定义内部接口&/p&&p&GW1(config-if)#exit&/p&&p&GW1(config)#access-list 1 permit host 100.0.0.1 /定义IG&/p&&p&GW1(config)#ip nat pool POOL1 192.168.0.1 192.168.0.3 prefix-length 24 type rotary&/p&&p&/建立一个IL地址池,范围是服务器所占用的地址范围,类型为rotary是指将在这段地址内轮循GW1(config)#ip nat inside destination list 1 pool POOL1 /对目的地址为列表内匹配的访问进行地址转换,把目的地址轮流转换成pool指定的地址,要注意的是如果服务器群里有一台或多台甚至是全部服务器不再工作了,路由器是无法辨别的,依旧会将流量进行轮循,不管服务器能否应答。&/p&&p&3,ip nat outside source&/p&&p&/外部地址转换,即是OG-&OL,由外部发起的流量,用法为隐藏外部主机真实地址。&/p&&p&ip nat ouside source static (OG) (OL) add-route&/p&&p&/add-route 是为了产生一条去往OL的路由.(查看路由表,多了一条去往OL的路由)&/p&&p&注意:如果ip nat ouside source list (list number) pool (pool name) add-route&/p&&p&虽然能转换OG-&OL,但是这样是产生不了一条去往(pool name)的路由,即使(pool name)只有一个地址。结局也是通信不成功的。&/p&&p&所以一般都是这样用ip nat ouside source static (OG) (OL) add-route ,单个地址映射。&/p&&p&ip nat outside source举例(隐藏外部主机真实地址)&/p&&p&如果希望禁止内部主机访问外网的同时让内部主机能访问指定的外部主机,但又不希望让内部主机了解其实自己已经访问了外网时,那么可将需要被访问的外部主机的OG地址转换成为一个内部或者一个虚假的空OL地址,外部主机只用访问这个虚假的OL地址就可以访问到真实的服务器了,达到隐藏真实IP的效果。&/p&&figure&&img src=&https://pic2.zhimg.com/v2-e839cac259bd83e1b66f54_b.jpg& data-rawwidth=&650& data-rawheight=&376& class=&origin_image zh-lightbox-thumb& width=&650& data-original=&https://pic2.zhimg.com/v2-e839cac259bd83e1b66f54_r.jpg&&&/figure&&br&&p&说明: ip nat inside / ip nat ouside -&/p&&p&配置:&/p&&p&GW1(config)#int s0&/p&&p&GW1(config-if)#ip nat outside /定义外部接口&/p&&p&GW1(config-if)#int e0&/p&&p&GW1(config-if)#ip add 192.168.0.1 255.255.255.0&/p&&p&GW1(config-if)#ip nat inside /定义内部接口&/p&&p&GW1(config-if)#exit&/p&&p&GW1(config-if)#ip nat outside source static 200.0.0.1 192.168.1.1 add-route&/p&&p&/定义OG转换为OL,后面加一个add-route是为了产生一条去往192.168.1.0的静态路由,否则内部主机去往网关后,网关查表时没有相关路由则丢弃报文。如果有默认路由或者本来就已经有路由了,则可省略该参数,也可以手工配置路由。&/p&&p&4,ip nat outside destination&/p&&p&cisco00都无此条命令!!&/p&&p&注:①ip nat inside source list n pool POOL_NAME&/p&&p&当list n为标准访问列表---access-list 1 permit a.b.c.d ,数据包的源地址满足listn (a.b.c.d),源地址转换为POOL_NAME地址&/p&&p&当list n为扩展访问列表--- access-list 100 permit tcp A B ,数据包的协议、源地址、目的地址、端口号等都要匹配list n , 源地址转换为POOL_NAME地址&/p&&p&②ip nat inside destination list n pool POOL_NAME&/p&&p&当list n为标准访问列表---access-list 1 permit a.b.c.d ,数据包的目的地址&/p&&p&满足list n (a.b.c.d), 目的地址转换为POOL_NAME地址&/p&&p&当list n为扩展访问列表--- access-list 100 permit tcp A B ,数据包的协议、源地址、目的地址、端口号等 都要匹配list n , 目的地址转换为POOL_NAME地址.&/p&&p&关于 网络技术知识交流欢迎添加Dennis_spo 交流学习。谢谢。&/p&
NAT是什么?NAT(Network Address Translation,网络地址转换)是1994年提出的。当在专用网内部的一些主机本来已经分配到了本地IP地址(即仅在本专用网内使用的专用地址),但现在又想和因特网上的主机通信(并不需要加密)时,可使用NAT方法。这种方法需要…
&figure&&img src=&https://pic3.zhimg.com/f491d68a6be558c7dcbc8e771fbb920a_b.jpg& data-rawwidth=&960& data-rawheight=&493& class=&origin_image zh-lightbox-thumb& width=&960& data-original=&https://pic3.zhimg.com/f491d68a6be558c7dcbc8e771fbb920a_r.jpg&&&/figure&&h2&&b&前言&/b&&/h2&&p&前面讲了搭建监控的方法,但是外网没法访问,怎么算是远程监控呢。因此这篇文章就分享下如何使外网能够访问自己家中电脑主机的经验。&/p&&p&想做到外网能访问内网,那首先要搞清楚自己家中网络搭建的结构,本篇就以本人家中为例。我家网络是电信天翼的一个盒子接入的,上面接上一个网件的路由器,再通过路由器来分配ip给各个连接上使用的电脑、手机。图如下:&figure&&img src=&https://pic3.zhimg.com/bc79446dbae9b_b.jpg& data-rawwidth=&746& data-rawheight=&214& class=&origin_image zh-lightbox-thumb& width=&746& data-original=&https://pic3.zhimg.com/bc79446dbae9b_r.jpg&&&/figure&&/p&&b&原理&/b&&p&看起来很复杂,原理其实很简单,由于我家的网络结构分为两层(如果更多层的网络结构以此类推就行了,如果一层结构的那更简单了)一层路由器,一层天翼盒子,那么首先把电脑上分配到的这个IP和要用的端口跟路由器上的某个端口绑定,然后再把路由器分配到的IP和绑定的端口映射到天翼盒子上的某个端口。本例中就拿树莓派上的监控网站做解释。内网要访问树莓派上的监控网站,那就要用分配到的IP+端口号,即为10.0.0.5:8080,在路由器的设置中将8080端口跟路由器上的某个空闲端口绑定,本例中即用5601端口,那么首先要做到的就是绑定完后能通过192.168.2.2:5601能访问到树莓派上的监控网站。在把路由的端口映射到天翼盒子中,本例就用盒子上的9090端口,那最终实现的就是在其他地方用外网能通过公网xx.xx.xx.xx:9090来访问家中监控网站。其实要做到内网穿透,可以用目前市面上的花生壳等软件,交点钱完事了,但是既然是自己动手搭架,能自己做的都自己做吧,算是练练手。&/p&&h2&&b&实现第一步&/b&&/h2&&p&前面废话讲了这么多,进入正篇,先讲下如何做到电脑绑定到路由。首先要做的就是第一步,打开你的电脑浏览器,输入&b&&i&ip.gs&/i&&/b&会获得一个IP(本人此处就打码了,免得有人杀到我家来),一般来说这个IP就是公网IP,但是也不一定,所以,可以直接在浏览器的地址栏输入这个IP,试试看能不能进入自家天翼盒子的控制页面,如果可以那恭喜里这是你家天翼盒子的公网地址,如果不行,那情况就复杂了,该怎么做我就不知道了,下面的内容可以不用看了,用其他现成的软件吧。&/p&&figure&&img src=&https://pic3.zhimg.com/dfaa2bc14c_b.jpg& data-rawwidth=&277& data-rawheight=&81& class=&content_image& width=&277&&&/figure&&p&首先记得把要映射的主机的IP设置为固定IP,不然下次自动分配的IP变了,又要重新配置咯,如果家里电脑主机比较多的话建议IP分配的后期去点,太靠前的IP容易被占用,造成IP冲突。IP设置完后,打开路由器的控制页面,我就拿我家网件的为例,其他路由器都差不多,这块的教程其实百度下也挺多的。找到内网映射这个选项&/p&&figure&&img src=&https://pic1.zhimg.com/6eaa53bc0c24c7bc73e739ba6e0a2ea9_b.jpg& data-rawwidth=&92& data-rawheight=&286& class=&content_image& width=&92&&&/figure&&p&选择端口映射、http,填写完IP,然后点击添加&/p&&figure&&img src=&https://pic1.zhimg.com/bf7ede3c1c9ad0_b.jpg& data-rawwidth=&377& data-rawheight=&89& class=&content_image& width=&377&&&/figure&&p&添加完后会发现,端口都不是我们想要的,选择中这条服务,点击编辑服务&/p&&figure&&img src=&https://pic3.zhimg.com/d3d571d111e0d4836420ce_b.jpg& data-rawwidth=&554& data-rawheight=&38& class=&origin_image zh-lightbox-thumb& width=&554& data-original=&https://pic3.zhimg.com/d3d571d111e0d4836420ce_r.jpg&&&/figure&&p&把“内部使用相同的端口范围”这个勾去掉,就可以编辑下面的端口了,外部端口组即为外部访问时要用的端口,挑个空闲的即可。内部端口组写上要映射的端口,点击应用,完事了。&figure&&img src=&https://pic1.zhimg.com/4dbb9c8e6_b.jpg& data-rawwidth=&554& data-rawheight=&116& class=&origin_image zh-lightbox-thumb& width=&554& data-original=&https://pic1.zhimg.com/4dbb9c8e6_r.jpg&&&/figure&&/p&&p&测试下,地址栏中输入天翼盒子分配给路由器的地址,192.168.2.2加上端口5601,萌萌哒的龙猫就出来了。&/p&&figure&&img src=&https://pic2.zhimg.com/28b1b3de6fba95c_b.jpg& data-rawwidth=&347& data-rawheight=&384& class=&content_image& width=&347&&&/figure&&p&这时候可能有小伙伴会问了,我咋知道天翼盒子给路由分配了啥地址呢。其实在路由器初始化设置的时候,给路由器配上静态的IP就可以了。如果之前是动态获取的,建议配置成静态的,不然下次路由地址变了就麻烦了。在路由器上找到这个配置的位置,重新配置下即可。&/p&&figure&&img src=&https://pic1.zhimg.com/6d78bd3c276_b.jpg& data-rawwidth=&725& data-rawheight=&255& class=&origin_image zh-lightbox-thumb& width=&725& data-original=&https://pic1.zhimg.com/6d78bd3c276_r.jpg&&&/figure&&p&还有简单的方法,有的路由器有远程管理的选项,这个地方显示的是路由器获取到外层分配给它的IP,如果你的路由是直接连外的话,那这里获取到的就是公网的地址。那我家路由的外层是天翼盒子,那这里获取到的就是天翼盒子给他的地址了。&figure&&img src=&https://pic4.zhimg.com/bc539ecdd91b2d1ef58a0cd197cad557_b.jpg& data-rawwidth=&553& data-rawheight=&274& class=&origin_image zh-lightbox-thumb& width=&553& data-original=&https://pic4.zhimg.com/bc539ecdd91b2d1ef58a0cd197cad557_r.jpg&&&/figure&&/p&&h2&&b&第二步:映射到外网&/b&&/h2&&p&做完了第一步,那就可以如法炮制映射到外网了,打开天翼盒子控制页面,用超级管理员用户登录,这里不知道超级用户登录用户名密码的可以自行百度下破译教程,很简单的,这里就不多说了。&/p&&figure&&img src=&https://pic4.zhimg.com/242caa93ee6c9c49a5666_b.jpg& data-rawwidth=&300& data-rawheight=&212& class=&content_image& width=&300&&&/figure&&p&应用-&高级NAT配置-&虚拟主机配置,打开设置页面:&/p&&figure&&img src=&https://pic2.zhimg.com/3c229f950e61b5b41b2c11d_b.jpg& data-rawwidth=&462& data-rawheight=&294& class=&origin_image zh-lightbox-thumb& width=&462& data-original=&https://pic2.zhimg.com/3c229f950e61b5b41b2c11d_r.jpg&&&/figure&&p&名称随便取,广域网端口这里配置一个空闲的端口,到时候通过这个端口访问,我们就用9090吧,然后虚拟主机的端口,配置要映射的端口,即为刚才路由上配置的5601端口,点击启用就完成了。如下:&/p&&figure&&img src=&https://pic3.zhimg.com/e95b585bcae4cf95b0cf3_b.jpg& data-rawwidth=&243& data-rawheight=&215& class=&content_image& width=&243&&&/figure&&p&迫不及待的在地址栏上敲上了公网IP+9090,但是等待了许久,却告诉我页面无法访问,这是咋回事呢。仔细检查了配置也没啥问题,后来发现不知道为啥,通过这个公网IP+端口访问,居然要FAN墙才行!(难道是哪里没配置好么,一直没搞懂为啥,希望有知道的大神透露下)先不管这么多,启动FQ软件,再次刷新,成功了,但是卡的要命,延迟至少20s以上,不过至少是能看了。找同事同学帮忙测试了下,似乎他们不用FAN墙就能访问,很神奇。。算是成功了吧。&figure&&img src=&https://pic4.zhimg.com/05d022fde9e940d2fc5c_b.jpg& data-rawwidth=&267& data-rawheight=&220& class=&content_image& width=&267&&&/figure&&/p&&p&通过同样的方法,可以配置树莓派的远程桌面等功能。值得一提的是普通家庭宽带是没有固定IP地址的,专线宽带才有。因此有可能你家路由的地址随时都会变掉。可以在树莓派上写个脚本&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&curl ip.gs
&/code&&/pre&&/div&&p&然后再写个脚本把输出出来的数据上传到某个网盘或者FTP或者发个邮件啥的定时执行下,就可以随时获得家中路由的公网地址了。&/p&&p&唉,折腾了这么久,其实最简单的搭建方法就是家里开一台电脑,然后登陆一个QQ,设置下远程自动接入,然后外网再开一个QQ,远程家里的QQ开启视频聊天,简易的监控平台就搭建好了,哈哈。&/p&
前言前面讲了搭建监控的方法,但是外网没法访问,怎么算是远程监控呢。因此这篇文章就分享下如何使外网能够访问自己家中电脑主机的经验。想做到外网能访问内网,那首先要搞清楚自己家中网络搭建的结构,本篇就以本人家中为例。我家网络是电信天翼的一个盒子…
&figure&&img src=&https://pic1.zhimg.com/v2-efc9b7ac9bddacf_b.jpg& data-rawwidth=&2126& data-rawheight=&1104& class=&origin_image zh-lightbox-thumb& width=&2126& data-original=&https://pic1.zhimg.com/v2-efc9b7ac9bddacf_r.jpg&&&/figure&&blockquote&原作者:阮一峰(&a href=&https://link.zhihu.com/?target=http%3A//ruanyifeng.com& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&ruanyifeng.com&/span&&span class=&invisible&&&/span&&/a&),本文由即时通讯网重新整理发布,感谢原作者的无私分享。&/blockquote&&h2&1、前言&/h2&&p&本系列文章的前两篇《&a href=&https://link.zhihu.com/?target=http%3A//www.52im.net/thread-.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&网络编程懒人入门(一):快速理解网络通信协议(上篇)&/a&》、《&a href=&https://link.zhihu.com/?target=http%3A//www.52im.net/thread-.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&网络编程懒人入门(二):快速理解网络通信协议(下篇)&/a&》快速介绍了网络基本通信协议及理论基础,建议开始阅读本文前先读完此2篇文章。&/p&&p&TCP 是互联网的核心协议之一,鉴于它的重要性,本文将单独介绍它的基础知识,希望能加深您对TCP协议的理解。&/p&&p&老规矩,为了让文字尽量通俗易懂、不浪费你的脑细胞,本文尽量点到为止,不对理论进行深入挖掘,如需深入理论细节,请参见下方参考资料中有关TCP协议的详细介绍和学习文章。&/p&&p&(本文同步发布于:&a href=&https://link.zhihu.com/?target=http%3A//www.52im.net/thread-.html& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://www.&/span&&span class=&visible&&52im.net/thread-1107-1-&/span&&span class=&invisible&&1.html&/span&&span class=&ellipsis&&&/span&&/a&)&br&&/p&&h2&2、系列文章&/h2&&p&&b&本文是系列文章中的第1篇,本系列文章的大纲如下:&/b&&/p&&blockquote&《&a href=&https://link.zhihu.com/?target=http%3A//www.52im.net/thread-.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&网络编程懒人入门(一):快速理解网络通信协议(上篇)&/a&》&br&《&a href=&https://link.zhihu.com/?target=http%3A//www.52im.net/thread-.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&网络编程懒人入门(二):快速理解网络通信协议(下篇)&/a&》&br&《&a href=&https://link.zhihu.com/?target=http%3A//www.52im.net/thread-.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&网络编程懒人入门(三):快速理解TCP协议一篇就够&/a&》(本文)&/blockquote&&h2&3、参考资料&/h2&&p&《&a href=&https://link.zhihu.com/?target=http%3A//www.52im.net/topic-tcpipvol1.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&TCP/IP详解&/a&-&a href=&https://link.zhihu.com/?target=http%3A//docs.52im.net/extend/docs/book/tcpip/vol1/11/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&第11章·UDP:用户数据报协议&/a&》&/p&&p&《&a href=&https://link.zhihu.com/?target=http%3A//www.52im.net/topic-tcpipvol1.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&TCP/IP详解&/a&-&a href=&https://link.zhihu.com/?target=http%3A//docs.52im.net/extend/docs/book/tcpip/vol1/17/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&第17章·TCP:传输控制协议&/a&》&/p&&p&《&a href=&https://link.zhihu.com/?target=http%3A//www.52im.net/topic-tcpipvol1.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&TCP/IP详解&/a&-&a href=&https://link.zhihu.com/?target=http%3A//docs.52im.net/extend/docs/book/tcpip/vol1/18/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&第18章·TCP连接的建立与终止&/a&》&/p&&p&《&a href=&https://link.zhihu.com/?target=http%3A//www.52im.net/topic-tcpipvol1.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&TCP/IP详解&/a&-&a href=&https://link.zhihu.com/?target=http%3A//docs.52im.net/extend/docs/book/tcpip/vol1/21/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&第21章·TCP的超时与重传&/a&》&/p&&p&《&a href=&https://link.zhihu.com/?target=http%3A//www.52im.net/thread-513-1-1.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&通俗易懂-深入理解TCP协议(上):理论基础&/a&》&/p&&p&《&a href=&https://link.zhihu.com/?target=http%3A//www.52im.net/thread-515-1-1.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&通俗易懂-深入理解TCP协议(下):RTT、滑动窗口、拥塞处理&/a&》&/p&&p&《&a href=&https://link.zhihu.com/?target=http%3A//www.52im.net/thread-258-1-1.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&理论经典:TCP协议的3次握手与4次挥手过程详解&/a&》&/p&&p&《&a href=&https://link.zhihu.com/?target=http%3A//www.52im.net/thread-275-1-1.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&理论联系实际:Wireshark抓包分析TCP 3次握手、4次挥手过程&/a&》&/p&&p&《&a href=&https://link.zhihu.com/?target=http%3A//www.52im.net/thread-180-1-1.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&计算机网络通讯协议关系图(中文珍藏版)&/a&》&/p&&p&《&a href=&https://link.zhihu.com/?target=http%3A//www.52im.net/thread-561-1-1.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&高性能网络编程(一):单台服务器并发TCP连接数到底可以有多少&/a&》&/p&&p&《&a href=&https://link.zhihu.com/?target=http%3A//www.52im.net/thread-566-1-1.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&高性能网络编程(二):上一个10年,著名的C10K并发连接问题&/a&》&/p&&p&《&a href=&https://link.zhihu.com/?target=http%3A//www.52im.net/thread-568-1-1.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&高性能网络编程(三):下一个10年,是时候考虑C10M并发问题了&/a&》&/p&&p&《&a href=&https://link.zhihu.com/?target=http%3A//www.52im.net/thread-578-1-1.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&高性能网络编程(四):从C10K到C10M高性能网络应用的理论探索&/a&》&/p&&p&《&a href=&https://link.zhihu.com/?target=http%3A//www.52im.net/thread-.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&不为人知的网络编程(一):浅析TCP协议中的疑难杂症(上篇)&/a&》&/p&&p&《&a href=&https://link.zhihu.com/?target=http%3A//www.52im.net/thread-.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&不为人知的网络编程(二):浅析TCP协议中的疑难杂症(下篇)&/a&》&/p&&p&《&a href=&https://link.zhihu.com/?target=http%3A//www.52im.net/thread-.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&不为人知的网络编程(三):关闭TCP连接时为什么会TIME_WAIT、CLOSE_WAIT&/a&》&/p&&p&《&a href=&https://link.zhihu.com/?target=http%3A//www.52im.net/thread-.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&不为人知的网络编程(四):深入研究分析TCP的异常关闭&/a&》&/p&&p&《&a href=&https://link.zhihu.com/?target=http%3A//www.52im.net/thread-.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&不为人知的网络编程(五):UDP的连接性和负载均衡&/a&》&/p&&p&《&a href=&https://link.zhihu.com/?target=http%3A//www.52im.net/thread-.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&不为人知的网络编程(六):深入地理解UDP协议并用好它&/a&》&/p&&p&《&a href=&https://link.zhihu.com/?target=http%3A//www.52im.net/thread-580-1-1.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&简述传输层协议TCP和UDP的区别&/a&》&/p&&p&《&a href=&https://link.zhihu.com/?target=http%3A//www.52im.net/thread-279-1-1.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&为什么QQ用的是UDP协议而不是TCP协议?&/a&》&/p&&p&《&a href=&https://link.zhihu.com/?target=http%3A//www.52im.net/thread-33-1-1.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&移动端即时通讯协议选择:UDP还是TCP?&/a&》&/p&&h2&4、TCP 协议的作用&/h2&&p&互联网由一整套协议构成。TCP 只是其中的一层,有着自己的分工。&/p&&figure&&img src=&https://pic1.zhimg.com/v2-1bbf760fe7_b.jpg& data-caption=&& data-rawwidth=&250& data-rawheight=&413& class=&content_image& width=&250&&&/figure&&p&▲ TCP 是以太网协议和 IP 协议的上层协议,也是应用层协议的下层协议&/p&&p&最底层的以太网协议(Ethernet)规定了电子信号如何组成数据包(packet),解决了子网内部的点对点通信。&br&&/p&&figure&&img src=&https://pic3.zhimg.com/v2-a689cff6ca6a8f182b38642_b.jpg& data-caption=&& data-rawwidth=&638& data-rawheight=&479& class=&origin_image zh-lightbox-thumb& width=&638& data-original=&https://pic3.zhimg.com/v2-a689cff6ca6a8f182b38642_r.jpg&&&/figure&&p&▲ 以太网协议解决了局域网的点对点通信&/p&&p&但是,以太网协议不能解决多个局域网如何互通,这由 IP 协议解决。&br&&/p&&figure&&img src=&https://pic1.zhimg.com/v2-aab7bb0838_b.jpg& data-caption=&& data-rawwidth=&750& data-rawheight=&355& class=&origin_image zh-lightbox-thumb& width=&750& data-original=&https://pic1.zhimg.com/v2-aab7bb0838_r.jpg&&&/figure&&p&▲ IP 协议可以连接多个局域网&/p&&p&IP 协议定义了一套自己的地址规则,称为 IP 地址。它实现了路由功能,允许某个局域网的 A 主机,向另一个局域网的 B 主机发送消息。&br&&/p&&figure&&img src=&https://pic1.zhimg.com/v2-280eabd89aea_b.jpg& data-caption=&& data-rawwidth=&600& data-rawheight=&410& class=&origin_image zh-lightbox-thumb& width=&600& data-original=&https://pic1.zhimg.com/v2-280eabd89aea_r.jpg&&&/figure&&p&▲ 路由器就是基于 IP 协议。局域网之间要靠路由器连接&/p&&p&路由的原理很简单。市场上所有的路由器,背后都有很多网口,要接入多根网线。路由器内部有一张路由表,规定了 A 段 IP 地址走出口一,B 段地址走出口二,......通过这套&指路牌&,实现了数据包的转发。&br&&/p&&figure&&img src=&https://pic2.zhimg.com/v2-c036edddcbfe_b.jpg& data-caption=&& data-rawwidth=&522& data-rawheight=&313& class=&origin_image zh-lightbox-thumb& width=&522& data-original=&https://pic2.zhimg.com/v2-c036edddcbfe_r.jpg&&&/figure&&p&▲ 本机的路由表注明了不同 IP 目的地的数据包,要发送到哪一个网口(interface)&/p&&p&IP 协议只是一个地址协议,并不保证数据包的完整。如果路由器丢包(比如缓存满了,新进来的数据包就会丢失),就需要发现丢了哪一个包,以及如何重新发送这个包。这就要依靠 TCP 协议。&br&&/p&&p&简单说,TCP 协议的作用是,保证数据通信的完整性和可靠性,防止丢包。&/p&&h2&5、TCP 数据包的大小&/h2&&p&以太网数据包(packet)的大小是固定的,最初是1518字节,后来增加到1522字节。其中, 1500 字节是负载(payload),22字节是头信息(head)。IP 数据包在以太网数据包的负载里面,它也有自己的头信息,最少需要20字节,所以 IP 数据包的负载最多为1480字节。&/p&&figure&&img src=&https://pic2.zhimg.com/v2-7cbe30f1c45fa_b.jpg& data-caption=&& data-rawwidth=&745& data-rawheight=&254& class=&origin_image zh-lightbox-thumb& width=&745& data-original=&https://pic2.zhimg.com/v2-7cbe30f1c45fa_r.jpg&&&/figure&&p&▲ IP 数据包在以太网数据包里面,TCP 数据包在 IP 数据包里面&/p&&p&TCP 数据包在 IP 数据包的负载里面。它的头信息最少也需要20字节,因此 TCP 数据包的最大负载是 1480 - 20 = 1460 字节。由于 IP 和 TCP 协议往往有额外的头信息,所以 TCP 负载实际为1400字节左右。因此,一条1500字节的信息需要两个 TCP 数据包。HTTP/2 协议的一大改进, 就是压缩 HTTP 协议的头信息,使得一个 HTTP 请求可以放在一个 TCP 数据包里面,而不是分成多个,这样就提高了速度。&br&&/p&&figure&&img src=&https://pic3.zhimg.com/v2-1c3bbf35c85bed_b.jpg& data-caption=&& data-rawwidth=&681& data-rawheight=&307& class=&origin_image zh-lightbox-thumb& width=&681& data-original=&https://pic3.zhimg.com/v2-1c3bbf35c85bed_r.jpg&&&/figure&&p&▲ 以太网数据包的负载是1500字节,TCP 数据包的负载在1400字节左右&/p&&h2&6、TCP 数据包的编号(SEQ)&/h2&&p&一个包1400字节,那么一次性发送大量数据,就必须分成多个包。比如,一个 10MB 的文件,需要发送7100多个包。发送的时候,TCP 协议为每个包编号(sequence number,简称 SEQ),以便接收的一方按照顺序还原。万一发生丢包,也可以知道丢失的是哪一个包。&/p&&p&第一个包的编号是一个随机数。为了便于理解,这里就把它称为1号包。假定这个包的负载长度是100字节,那么可以推算出下一个包的编号应该是101。这就是说,每个数据包都可以得到两个编号:自身的编号,以及下一个包的编号。接收方由此知道,应该按照什么顺序将它们还原成原始文件。&/p&&figure&&img src=&https://pic3.zhimg.com/v2-41e80ef75cd4e859d289eadaf1c0828f_b.jpg& data-caption=&& data-rawwidth=&517& data-rawheight=&247& class=&origin_image zh-lightbox-thumb& width=&517& data-original=&https://pic3.zhimg.com/v2-41e80ef75cd4e859d289eadaf1c0828f_r.jpg&&&/figure&&p&▲ 当前包的编号是45943,下一个数据包的编号是46183,由此可知,这个包的负载是240字节&/p&&h2&7、TCP 数据包的组装&/h2&&p&收到 TCP 数据包以后,组装还原是操作系统完成的。应用程序不会直接处理 TCP 数据包。对于应用程序来说,不用关心数据通信的细节。除非线路异常,收到的总是完整的数据。应用程序需要的数据放在 TCP 数据包里面,有自己的格式(比如 HTTP 协议)。&/p&&p&TCP 并没有提供任何机制,表示原始文件的大小,这由应用层的协议来规定。比如,HTTP 协议就有一个头信息Content-Length,表示信息体的大小。对于操作系统来说,就是持续地接收 TCP 数据包,将它们按照顺序组装好,一个包都不少。&/p&&p&操作系统不会去处理 TCP 数据包里面的数据。一旦组装好 TCP 数据包,就把它们转交给应用程序。TCP 数据包里面有一个端口(port)参数,就是用来指定转交给监听该端口的应用程序。&/p&&figure&&img src=&https://pic2.zhimg.com/v2-1551bfe483c550b2ecff_b.jpg& data-caption=&& data-rawwidth=&610& data-rawheight=&293& class=&origin_image zh-lightbox-thumb& width=&610& data-original=&https://pic2.zhimg.com/v2-1551bfe483c550b2ecff_r.jpg&&&/figure&&p&系统根据 TCP 数据包里面的端口,将组装好的数据转交给相应的应用程序。上图中,21端口是 FTP 服务器,25端口是 SMTP 服务,80端口是 Web 服务器。&/p&&p&应用程序收到组装好的原始数据,以浏览器为例,就会根据 HTTP 协议的Content-Length字段正确读出一段段的数据。这也意味着,一次 TCP 通信可以包括多个 HTTP 通信。&/p&&h2&8、慢启动和 ACK&/h2&&p&服务器发送数据包,当然越快越好,最好一次性全发出去。但是,发得太快,就有可能丢包。带宽小、路由器过热、缓存溢出等许多因素都会导致丢包。线路不好的话,发得越快,丢得越多。&/p&&p&最理想的状态是,在线路允许的情况下,达到最高速率。但是我们怎么知道,对方线路的理想速率是多少呢?答案就是慢慢试。&/p&&p&TCP 协议为了做到效率与可靠性的统一,设计了一个慢启动(slow start)机制。开始的时候,发送得较慢,然后根据丢包的情况,调整速率:如果不丢包,就加快发送速度;如果丢包,就降低发送速度。&/p&&p&Linux 内核里面设定了(常量TCP_INIT_CWND),刚开始通信的时候,发送方一次性发送10个数据包,即&发送窗口&的大小为10。然后停下来,等待接收方的确认,再继续发送。默认情况下,接收方每收到两个 TCP 数据包,就要发送一个确认消息。&确认&的英语是 acknowledgement,所以这个确认消息就简称 ACK。&/p&&p&&b&ACK 携带两个信息:&/b&&/p&&blockquote&1)期待要收到下一个数据包的编号;&br&2)接收方的接收窗口的剩余容量。&/blockquote&&p&发送方有了这两个信息,再加上自己已经发出的数据包的最新编号,就会推测出接收方大概的接收速度,从而降低或增加发送速率。这被称为&发送窗口&,这个窗口的大小是可变的。&/p&&figure&&img src=&https://pic1.zhimg.com/v2-bca9fd116f9d9f883c36fc_b.jpg& data-caption=&& data-rawwidth=&666& data-rawheight=&586& class=&origin_image zh-lightbox-thumb& width=&666& data-original=&https://pic1.zhimg.com/v2-bca9fd116f9d9f883c36fc_r.jpg&&&/figure&&p&▲ 每个 ACK 都带有下一个数据包的编号,以及接收窗口的剩余容量,双方都会发送 ACK&/p&&blockquote&&b&注意:&/b&由于 TCP 通信是双向的,所以双方都需要发送 ACK。两方的窗口大小,很可能是不一样的。而且 ACK 只是很简单的几个字段,通常与数据合并在一个数据包里面发送。&/blockquote&&figure&&img src=&https://pic4.zhimg.com/v2-da11a1adbd62f0061740daaa_b.jpg& data-caption=&& data-rawwidth=&600& data-rawheight=&238& class=&origin_image zh-lightbox-thumb& width=&600& data-original=&https://pic4.zhimg.com/v2-da11a1adbd62f0061740daaa_r.jpg&&&/figure&&p&上图一共4次通信。第一次通信,A 主机发给B 主机的数据包编号是1,长度是100字节,因此第二次通信 B 主机的 ACK 编号是 1 + 100 = 101,第三次通信 A 主机的数据包编号也是 101。同理,第二次通信 B 主机发给 A 主机的数据包编号是1,长度是200字节,因此第三次通信 A 主机的 ACK 是201,第四次通信 B 主机的数据包编号也是201。&/p&&p&即使对于带宽很大、线路很好的连接,TCP 也总是从10个数据包开始慢慢试,过了一段时间以后,才达到最高的传输速率。这就是 TCP 的慢启动。&/p&&h2&9、数据包的遗失处理&/h2&&p&TCP 协议可以保证数据通信的完整性,这是怎么做到的?&/p&&p&前面说过,每一个数据包都带有下一个数据包的编号。如果下一个数据包没有收到,那么 ACK 的编号就不会发生变化。&/p&&p&举例来说,现在收到了4号包,但是没有收到5号包。ACK 就会记录,期待收到5号包。过了一段时间,5号包收到了,那么下一轮 ACK 会更新编号。如果5号包还是没收到,但是收到了6号包或7号包,那么 ACK 里面的编号不会变化,总是显示5号包。这会导致大量重复内容的 ACK。&/p&&p&如果发送方发现收到三个连续的重复 ACK,或者超时了还没有收到任何 ACK,就会确认丢包,即5号包遗失了,从而再次发送这个包。通过这种机制,TCP 保证了不会有数据包丢失。&/p&&figure&&img src=&https://pic1.zhimg.com/v2-f7fbc0d8e6_b.jpg& data-caption=&& data-rawwidth=&424& data-rawheight=&492& class=&origin_image zh-lightbox-thumb& width=&424& data-original=&https://pic1.zhimg.com/v2-f7fbc0d8e6_r.jpg&&&/figure&&p&▲ Host B 没有收到100号数据包,会连续发出相同的 ACK,触发 Host A 重发100号数据包&/p&&p&(原文链接:&a href=&https://link.zhihu.com/?target=http%3A//www.ruanyifeng.com/blog/2017/06/tcp-protocol.html& class=& wrap exter}

我要回帖

更多关于 edianpingcom商家登录 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信