Android Studio --- [学习笔记]TCP(第2弹)、GridView、ScrollView

说明

  • 这篇主要接上一篇Android Studio — > [学习笔记]RadioButton、CheckBox、ImageView、ListView、TCP的三次握手
  • 对上面回答的细解,并用JS伪代码,对TCP三次握手和四次挥手的简单实现.
  • Android的基本了解到此篇结束,后续会根据具体情况深度学习.

2.y TCP的三次握手和四次挥手(第2弹)

  • 参考
  • 下面娓娓道来(逐字敲)上一篇提出问题的解析

2.y.1 三次握手

  • 三次握手(Three-way Handshake)其实就是指建立一个TCP连接时,需要客户端和服务器总共发送3个包。进行三次握手的主要作用就是为了确认双方的接收能力和发送能力是否正常、指定自己的初始化序列号为后面的可靠传送做准备。实质上其实就是连接服务器指定端口,建立TCP连接,并同步连接双方的序列号和确认号,交换TCP窗口大小信息.

  • 刚开始客户端处于Closed的状态,服务器处于Listen状态.进行三次握手:

    • (1)第一次握手: 客户端给服务端发一个SYN报文,并指明客户端的初始化序列号ISN©.此时客户端处于SYN_SENT状态;首部的同步位SYN=1,初始序号seq=x,SYN=1的报文段不能携带数据,但要消耗掉一个序号
    • (2)第二次握手: 服务器收到客户端的SYN报文后,会以自己的SYN报文作为应答,并且也是指定了自己的初始化序列号ISN(s)。同时会把客户端的ISN+1作为ACK的值,表示自己已经收到了客户端的SYN,此时服务器处于SYN_RCVD的状态;在确认报文段中SYN=1,ACK=1,确认号ack=x+1(表示希望收到下一个的序号),初始序号seq=y
    • (3)第三次握手:客户端收到SYN报文之后,会发送一个ACK报文,当然,也是一样把服务器的ISN+1作为ACK的值,表示已经收到了服务端的SYN报文,此时客户端处于ESTABLISHED状态。服务器收到ACK报文之后,也处于ESTABLISHED状态,此时,双方已建立起了连接;确认报文段ACK=1,确认号ack=y+1,序号seq=x+1,ACK报文段可以携带数据,不携带数据则不消耗序号
  • 发送第一个SYN的一端将执行主动打开(active open),接收这个SYN并发回下一个SYN的另一端执行被动打开(passive open).

  • 在socket编程中,客户端执行connect()时,将触发三次握手。

2.y.2 为什么需要三次握手,两次不行吗?

  • 为了弄清这个问题,我们需要先弄明白三次握手的目的是什么,能不能只用两次握手来达到同样的目的.

    • (1)第一次握手: 客户端发送网络包,服务端收到,这样服务端就能得出结论 -> 客户端的发送能力、服务端的接收能力是正常的
    • (2)第二次握手: 服务端发包,客户端收到了,这样客户端就能得出结论: 服务端的接收、发送能力,客户端的接收、发送能力是正常的。不过此时服务器并不能确认客户端的接收能力是否正常。
    • (3)第三次握手: 客户端发包,服务端收到,这样服务器就能得出结论: 客户端的接收、发送能力正常,服务器自己的发送、接收能力也正常。
  • 因此,需要三次握手才能确认双方的接收与发送能力是否正常。

  • 如果是用两次握手,则会出现下面这种情况:

如客户端发出连接请求,但因连接请求报文丢失而未收到确认,于是客户端再重传一次连接请求。后来收到了确认,建立了连接。数据传输完毕后,就释放了连接,客户端共发出了两个连接请求报文段,其中第一个丢失,第二个到达了服务端,但是第一个丢失的报文段只是再某些网络结点长时间滞留了,延误到连接释放以后的某个时间才到达服务端,此时服务端误认为客户端又发出了一次新的连接请求,于是就向客户端发出确认报文段,同意建立连接,就建立新的连接了,此时客户端忽略服务器发来的确认,也不发送数据,则服务端一致等待客户端发送数据,造成资源浪费.

2.y.3 什么是半连接队列?

  • 服务器第一次收到客户端的SYN之后,就处于SYN_RCVD状态,此时双方还没有完全建立其连接,服务器会把此种状态下请求连接放在一个队列里,我们把这种队列称之为半连接队列

  • 当然还有一个全连接队列,就是已经完成三次握手,建立起连接的就会放到全连接队列种。如果队列满了就有可能会出现丢包现象。

  • SYN-ACK重传次数:

服务器发送完SYN-ACK包,如果未收到客户确认包,服务器进行首次重传,等待一段时间仍未收到客户确认包,进行第二次重传。如果重传次数超过系统规定的最大重传次数,系统将该连接信息从半连接队列中删除。注意,每次重传等待的时间不一定相同,一般会是指数增长,例如间隔时间1s,2s,4s,8s…

2.y.4 ISN(Initial Sequence Number)是固定的吗?

  • 当一端为建立连接而发送它的SYN时,它为连接选择一个初始序号。ISN随时间而变化,因此每个连接都将具有不同的ISN。ISN可以看作是一个32比特的计数器,每4ms加1.这样选择序号的目的在于防止在网络延迟的分组在以后被传送,而导致某个连接的一方对它做错误的解释。

  • 三次握手的其中一个重要功能是客户端和服务端交换ISN(Initial Sequence Number),以便让对方直到接下来接收数据的时候如何按序列号组装数据。如果ISN是固定的,攻击者很容易猜出后续的确认号,因此ISN是动态生成的.

2.y.5 三次握手过程中可以携带数据吗?

  • 其实第三次握手的时候,是可以携带数据的。但是,第一次、第二次握手不可以携带数据
  • 为什么这样呢? 假如第一个握手可以携带数据的话,如果有人要恶意攻击服务器,那他每次都在第一次握手中的SYN报文中放入大量的数据。因为攻击者根本就不理服务器的接收、发送能力是否正常,然后疯狂着重复发SYN报文的话,这会让服务器花费很多时间、内存控件来接收这些报文。
  • 也就是说,第一次握手不可以放数据,其中一个简单的原因就是会让服务器更加容易受到攻击。而对于第三次的话,此时客户端已经处于ESTABLISHED状态。对于客户端来说,他已经建立起连接了,并且也已经直到服务器的接收、发送能力是正常的了,所以能携带数据也没啥毛病。

2.y.6 SYN攻击是什么?

  • 服务器端的资源分配是在二次握手时分配的,而客户端的资源分配是在完成三次握手时分配的,所以服务器容易收到SYN洪泛攻击。SYN攻击就是Client在短时间内伪造大量不存在的IP地址,并向Server不断地发送SYN包,Server则回复确认包,并等待Client确认,由于源地址不存在,因此Server需要不断重发至超时,这些伪造地SYN包将长时间占用未连接队列,导致正常的SYN请求因为队列满而被丢弃,从而引起网络拥塞甚至系统瘫痪。SYN攻击是一种典型的DoS/DDoS攻击。
  • 检测SYN攻击非常的方便,当你在服务器上看到大量的半连接状态时,特别是源IP地址是随机的,基本上可以断定这是一次SYN攻击。在Linux/Unix上可以使用系统自带的netstats命令来检测SYN攻击。

netstat -n -p TCP|grep SYN_RECV

  • 常见的防御SYN攻击的方法有如下几种:
    • 缩短超时(SYN Timeout)时间
    • 增加最大半连接数
    • 过滤网关防护
    • SYN cookies技术

2.y.7 四次挥手

  • 建立一个连接需要三次握手,而终止一个连接要经过四次挥手。这由TCP的半关闭(half-close)造成的。所谓的半关闭,其实就是TCP提供了连接的一端在结束它的发送后还能接收来自另一端数据的能力。

  • TCP的连接的拆除需要发送四个包,因此成为四次挥手(Four-way handshake),客户端或服务器均可主动发送挥手动作。

  • 刚开始双方都处于ESTABLISHED状态,假如是客户端先发起关闭请求。四次挥手的过程如下:

    • 第一次挥手: 客户端发送一个FIN报文,报文中会指定一个序列号。此时客户端处于FIN_WAIT1状态.

      即发出连接释放报文段(FIN=1,序号seq=u),并停止发送数据,主动关闭TCP连接,进入FIN)WAIT1(终止等待1)状态,等待服务端的确认.

    • 第二次挥手: 服务端收到FIN之后,会发送ACK报文,且把客户端的序列号值+1作为ACK报文的序列号值,表明已经收到客户端的报文了,此时服务端处于CLOSE_WAIT状态

      即服务器收到连接释放报文段后即发出确认报文段(ACK=1,确认号ack=u+1,序号seq=v),服务器进入CLOST_WAIT(关闭等待)状态,此时的TCP处于半关闭状态,客户端到服务端连接释放。客户端收到服务端的确认后,进入FIN_WATI2(终止等待2)状态,等待服务端发出的连接释放报文段.

    • 第三次挥手: 如果服务端也想断开连接了,和客户端的第一次挥手一样,发送FIN报文,且指定一个序列号。此时服务器处于LAST_ACK状态

      即服务端没有要向客户端发送的数据,服务端发出连接释放报文段(FIN=1, ACK=1, 序号 seq=w, 确认号 ack=u+1), 服务端进入LAST_ACK(最后确认)状态,等待客户端的确认.

    • 第四次挥手: 客户端收到FIN之后,一样发送一个ACK报文作为应答,且把服务器端的程序列号值+1作为自己ACK报文的序列号值,此时客户端处于TIME_WAIT状态。需要过一阵子以确保服务端收到自己的ACK报文之后才会进入CLOSED状态,服务端收到ACK报文之后,就处于关闭连接了,处于CLOSED状态

      即客户端收到服务器的连接释放报文后,对此发出确认报文段(ACK=1,seq=u+1,ack=w+1),客户端进入TIME_WAIT(时间等待)状态.此时TCP未释放掉,需要经过时间等待计时器设置的时间2MSL后,客户端进入

  • 收到一个FIN只意味着在这一方向上没有数据流动。客户端执行主动关闭并进入TIME_WAIT是正常的,服务端通常执行被动关闭,不会进入TIME_WAIT状态

2.y.8 为什么需要四次

  • 因为当服务端收到客户端的SYN连接请求报文后可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当服务器收到FIN报文时,很可能并不会立即关闭(因为还有数据要传输),所以只能先回复一个ACK报文,告诉客户端,“你发的FIN报文我收到了”。只有等到我服务端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四次挥手。

2.y.9 2MSL等待状态

TIME_WAIT状态也成为了2MSL等待状态。每个具体TCP实现必须选择一个报文段最大生存时间(Maximum Segment Lifetime),它是任何报文段被丢弃前在网络内的最长时间。这个时间是有限的,因为TCP报文段以IP数据包在网络内传输,而IP数据报则有限制其生存时间的TTL字段。

对一个具体实现所给定的MSL值,处理的原则是: 当TCP执行一个主动关闭,并发回最后一个ACK,该连接必须在TIME_WATI状态停留的时间为2倍的MSL。这样可让TCP再次发送最好的ACK以防这个ACK丢失(另一端超时并重发最后的FIN)。

这种2MSL等待的另一个结果是这个TCP连接在2MSL等待期间,定义这个连接的插口(客户的IP地址和端口号,服务器的IP地址和端口号)不能再被使用。这个连接只能在2MSL结束后才能再被使用。

2.y.10 四次挥手释放连接时,等待2MSL的意义

MSL是Maximum Segment Lifetime的英文缩写,可以译为"最长 报文段寿命",它是任何报文在网络上存在的最长的时间,超过这个时间报文将被丢弃。

为了保证客户端发送的最后一个ACK报文端报文段能够到达服务器。因为这个ACK有可能丢失,从而导致处在LAST-ACK状态的服务器收不到对FIN-ACK的确认报文。服务器会超时重传这个FIN-ACK,接着客户端再重传一次确认,重新启动时间等待计时器。最后客户端和服务器都能正常的关闭,一但这个ACK丢失的话,服务器就无法正常的进入关闭连接状态。

两个理由

  1. 保证客户端发送的最后一个ACK报文段能够到达服务端。
     
    这个ACK报文段有可能丢失,使得处于LAST-ACK状态的B收不到已发送的FIN+ACK报文段的确认,服务端超时重传FIN+ACK报文段,而客户端能在2MSL时间内收到这个重传的FIN+ACK报文段,接着客户端重传一次确认,重新启动2MSL计时器,最后客户端和服务端都进入CLOSED状态,若客户端再TIME-WAIT状态不等待一段时间,而是发送完ACK报文段后立即释放连接,则无法收到服务端重传的FIN+ACK报文段,所以不会再发送一次确认报文段,则服务端无法正常进入到CLOSED状态。
  2. 防止"已失效的连接请求报文段"出现在本连接中。
     
    客户端在发送完最后一个ACK报文段后,再经过2MSL,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失,使下一个新的连接中不会出现这种旧的连接请求报文段。

2.y.11 为什么TIME_WAIT状态需要经过2MSL才能返回到CLOSE状态?

理论上,四个报文都发送完毕,就可以直接进入CLOSE状态了,但是可能网络是不可靠的,有可能最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文

2.9 网格视图GridView(略)

  • 常用属性
  • Adapter接口
  • Demo演示

2.10 滚动视图ScrollView

  • 垂直滚动: ScrollView
  • 水平滚动: HorizontalScrollView
     

ScrollView的子元素只允许有一个根结点

2.10.1 竖直方向滚动的基本使用

  • activity_main.xml
<ScrollView xmlns:android:="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><LinearLayout><!-- <Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="300dp"android:text="Test "android:textAllCaps="false" /> * N --></LinearLayout>
</ScrollView>

2.10.2 水平方向的滚动

<HorizontalScroll><LinearLayout><!-- <Buttonandroid:layout_width="200dp"android:layout_height="300dp"android:text="Test"android:textAllCaps="false"/>  * N --></LinearLayout>
</HorizontalScroll>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/250393.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL中varchar最大长度是多少

一. varchar存储规则&#xff1a; 4.0版本以下&#xff0c;varchar(20)&#xff0c;指的是20字节&#xff0c;如果存放UTF8汉字时&#xff0c;只能存6个&#xff08;每个汉字3字节&#xff09; 5.0版本以上&#xff0c;varchar(20)&#xff0c;指的是20字符&#xff0c;无论存放…

bzoj 1232: [Usaco2008Nov]安慰奶牛cheer【最小生成树】

有趣 每条边在算答案的时候被算了二倍的边权值加上两个端点的权值&#xff0c;然后睡觉点额外加一次 所以可以用这个权做MST&#xff0c;然后加上点权最小的点 #include<iostream> #include<cstdio> #include<algorithm> using namespace std; const int N1…

JavaScript --- [学习笔记]观察者模式 理解对象 工厂模式 构造函数模式

说明 本系列(JS基础梳理)为后面TCP的模拟实现做准备本篇的主要内容: 观察者模式、工厂模式、构造函数模式 和 对对象的理解 1. 观察者模式 参考JavaScript设计模式 1.1 消息注册方法 “将订阅者注册的消息推入到消息队列中” [算法思路] : 在推入到消息队列时,如果此消息…

java_day19_MVC和配置文件

简单的MVC设计 MVC的全名是Model View Controller&#xff0c;是模型(model)&#xff0d;视图(view)&#xff0d;控制器(controller)的缩写&#xff0c;是一种软件设计典范。它是用一种业务逻辑、数据与界面显示分离的方法来组织代码&#xff0c;将众多的业务逻辑聚集到一个部件…

Problem I: 打印金字塔

#include<stdio.h> int main() {int n,i,j,k;scanf("%d",&n);for(i1;i<n;i){for(j1;j<n-i;j)printf(" ");for(k1;k<2*i-1;k)printf("*");printf("\n");}return 0; } HINT 用双重循环做&#xff0c;外循环代表行数&…

webpack --- 发布环境的配置 代码压缩 代码分类

说明 源代码本篇主要对发布环境的配置说明前面2点是对webpack的一个复习.第3点开始,逐步配置部署代码 1. Webpack发布的策略 2.1 在实际开发中,一般会有两套方案: 开发期间的项目:包含了测试文件、测试数据、开发工具、测试工具等相关配置,有利于项目的开发和测试,但是这些文…

salesforce lightning零基础学习(三) 表达式的!(绑定表达式)与 #(非绑定表达式)

在salesforce的classic中&#xff0c;我们使用{!expresion}在前台页面展示信息&#xff0c;在lightning中&#xff0c;上一篇我们也提及了&#xff0c;如果展示attribute的值&#xff0c;可以使用{!v.expresion}展示信息。 lightning在component中解析动态值的时候&#xff0c;…

sqlserver学习3---sql函数

一、SQL DML 和 DDL 可以把 SQL 分为两个部分&#xff1a;数据操作语言 (DML) 和 数据定义语言 (DDL)。 SQL (结构化查询语言)是用于执行查询的语法。但是 SQL 语言也包含用于更新、插入和删除记录的语法。 查询和更新指令构成了 SQL 的 DML 部分&#xff1a; SELECT - 从数据库…

JavaScript --- [学习笔记] 原型模式

说明 接JavaScript — > [学习笔记]观察者模式 & 理解对象 & 工厂模式 & 构造函数模式上一篇构造函数模式创建的实例,不同实例的同一个方法是不相等的,为了解决这个问题.出现了原型模式 1. 原型模式 具体做法是,不在构造函数中定义对象实例的信息,而是将这些…

网络协议各层概述

网络协议概述 OSI是一个开放性的通信系统互连参考模型&#xff0c;他是一个定义得非常好的协议规范。OSI模型有7层结构&#xff0c;每层都可以有几个子层。 OSI的7层从上到下分别是 7 应用层 6 表示层 5 会话层 4 传输层 3 网络层 2 数据链路层 1 物理层&#xff1b; 其中高层&…

A start job is running for Raise network interface(5min 13s )问题解决方法

命令&#xff1a;sudo vim /etc/systemd/system/network-online.target.wants/networking.service将里面的TimeoutStartSec5min 修改为TimeoutStartSec2sec 然后重启系统&#xff0c;就可以生效了&#xff0c;开机速度很快 转载于:https://www.cnblogs.com/sea-stream/p/98615…

javascript --- 实现对象的深拷贝

浅拷贝和深拷贝 浅拷贝: 只拷贝一层.当对象是复杂数据类型(Object、 Array)时,只拷贝引用深拷贝: 多层拷贝.复杂数据类型,会重新分配内存空间. 实现浅拷贝的2种方法 使用for ... in 实现 var obj {name: marron,age: 18,msg: {sex: "1" } } var o {}; for(let …

Qt与FFmpeg联合开发指南(二)——解码(2):封装和界面设计

与解码相关的主要代码在上一篇博客中已经做了介绍&#xff0c;本篇我们会先讨论一下如何控制解码速度再提供一个我个人的封装思路。最后回归到界面设计环节重点看一下如何保证播放器界面在缩放和拖动的过程中保证视频画面的宽高比例。 一、解码速度 播放器播放媒体文件的时候播…

Bzoj1051 受欢迎的牛

每一头牛的愿望就是变成一头最受欢迎的牛。现在有 N 头牛&#xff0c;给你 M 对整数 (A,B)&#xff0c;表示牛 A 认为牛 B 受欢迎。这种关系是具有传递性的&#xff0c;如果 A 认为 B 受欢迎&#xff0c;B 认为 C 受欢迎&#xff0c;那么牛 A 也认为牛 C 受欢迎。你的任务是求出…

node --- 模块加载机制

1. Node.js中模块加载机制 1.1 模块查找规则-当模块拥有路径但没有后缀时 require(./find.js); require(./find);require方法根据模块路径查找模块,如果是完整路径,直接进入模块如果模块后缀省略,先找同名JS文件再找同名JS文件夹 require(./find); // 以上会先找到命令行目录…

51Nod 蜥蜴和地下室(搜索)

哈利喜欢玩角色扮演的电脑游戏《蜥蜴和地下室》。此时&#xff0c;他正在扮演一个魔术师。在最后一关&#xff0c;他必须和一排的弓箭手战斗。他唯一能消灭他们的办法是一个火球咒语。如果哈利用他的火球咒语攻击第i个弓箭手&#xff08;他们从左到右标记&#xff09;&#xff…

多线程——实现Runnable接口实现一个多线程

实现Runnable接口实现一个多线程 Runnable接口源码&#xff1a; package java.lang; //Runnable接口源码只有一个run方法 public interface Runnable {public abstract void run(); } 实现Runnable的两个多线程类&#xff1a; public class RunnableThread1 implements Runnabl…

javascript --- 文件上传即时预览 闭包实现多图片即时预览

使用javascript原生功能实现,点击上传文件,然后再网页上显示出来 1. 初级显示 1.1 准备一个input标签和一个img标签 <input typefile id"file"> <img id"preview" src"">1.2 js代码如下 // 将上传的图片显示到页面上function sho…

第一次作业:深入Linux源码分析进程模型

一.进程的概念 第一&#xff0c;进程是一个实体。每一个进程都有它自己的地址空间&#xff0c;一般情况下&#xff0c;包括文本区域&#xff08;text region&#xff09;、数据区域&#xff08;data region&#xff09;和堆栈&#xff08;stack region&#xff09;。文本区域存…

关于模型验证那点事儿

今天应笑笑老师之问&#xff0c;做了一个模型验证的例子&#xff0c;发现之前对这个东西的理解太片面&#xff0c;重新整理了一下思路 字段验证优先级高于类验证 什么是类验证呢&#xff1f;就是两个字段组合的验证&#xff0c;比如你Admin不允许修改密码&#xff0c;你修改密码…