一个安静优雅的hexo主题,拥有轻量化页面。

使用git bash更新博客遇到的问题与解决方案

写在前面

此帖仅供参考,不一定适合你的情况,请谨慎采纳,造成的一切后果作者不承担责任。

需要确认的

sshkey是否生成并添加到github

如果没有
解决方案

问题描述与解决方案

(框架为hexo6.0.0,git bash版本v2.34.1.windows.1主题是ayer)作者在使用git bash部署博客到github时遇到的问题如下:

  • error:10053
    • 解决方案1(上传较大文件时出现):在git中输入git config –global http.postBuffer 524288000
    • 解决方案2(修改postBuffer后还是不行):网络问题(github的服务器在国外所以连接不稳定),多hexo g && hexo d几次就行
  • 添加了sshkey但还是出现了OpenSSL SSL_connect: Connection was aborted in connection to github.com:443
    • 解决方案1:挂梯子
    • 挂了梯子还是出现:看下面情况的解决方案1
  • fatal: unable to access https://github.com/ xxxx: Failed to connect to 127.0.0.1 port xxxx:
  • 补充:修改代理可以直接在C盘用户文件夹内搜gitconfig文件,直接进行修改,修改完建议重启git bash以检验。

梯子推荐:魔戒(需付费)

异常与异常处理

前言

本文为华为开发者学堂-面向对象编程的课程笔记,仅供个人学习使用。

异常与异常处理

什么是异常和异常处理

异常:异常是在程序的运行过程中所发生的不正常的事件,它会中断正在运行的程序。在Java中,它是一种特殊的对象,类型为java.lang.Exception或其子类
如何解决呢?

  • 程序员通过代码堵住程序可能出现的漏洞
  • 程序员在设计程序的阶段预测可能出现的异常并写好对应措施,当程序遇到这些异常时,会按照事先规定好的代码去处理异常而不含让程序中断运行
  • IDE和编程语言提供的异常处理机制(标红,报错等等)

异常处理机制

  • Java的异常处理是通过try、catch、finally、throw和throws五个关键字来完成的,try执行可能产生异常的代码,catch捕获异常,无论是否发生异常,finally中的代码总能执行,throws声明方法可能要抛出的各种异常,throw手动抛出异常
  • Java内的异常Exception是一个,catch要捕获的是Exception类的对象
    • 常见的异常类型
      • Exception:异常层次结构的父类
      • ArithmeticException:算术错误
      • InputMismatchException:输入格式不匹配 (比如要求输入int但得到字符串)
      • ArrayIndexOutOfBoundsException:数组下标越界
      • NullPointerException:尝试访问null对象成员 (比如你将一个字符串用equals()跟指向null的字符串比较)
      • ClassNotFoundException:不能加载所需的类 (比如打错类名了)
      • lllegalArgumentException:方法接收到非法参数
      • ClassCastException:对象强制类型转换错误
      • NumberFormatException:数字格式转换异常 (比如把“abc”转换成数字)
  • 在catch块中处理异常:
    • 使用**System.err.println()**来输出错误反馈信息
    • 使用**e.printStackTrace()**来输出异常的堆栈信息并跟踪异常产生的位置和过程
    • 使用**e.getMessage()**得到描述异常的字符串,而该字符串是printStackTrace()输出信息的一部分,如果异常没有描述字符串则输出null
  • 关于多重catch块
    • 排列catch语句的顺序:先子类后父类
    • 发生异常时按顺序逐个匹配
    • 只执行第一个与异常类型匹配的catch语句

try-catch-finally

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//使用try-catch-finally处理、捕捉异常,分为三种情况:
public void method(){
try{
//可能产生异常的代码块
}
catch(异常类型 ex){
//对异常进行处理的代码段
}
finally{
//无论如何都会执行的代码段,除了极个别情况
}
}
//第一种情况:无事发生,执行顺序:try——>finally(跳过catch)
//第二种情况:产生可以处理的异常:try(try内产生异常的行后面的代码不会被执行)——>catch——>finally(除非catch内的处理方法里有退出Java虚拟机方法System.exit(1),否则继续)
//第三种情况:产生异常类型不匹配:try——>产生的异常会和catch的异常类型进行匹配,如果不匹配则中断运行,但是一定会在中断之前执行finally

使用throws声明异常

如果一个方法体可能抛出异常,我们使用throws声明可能抛出的各种异常,异常之间用逗号隔开
调用者的对应方式有:

  • 处理异常
  • 继续声明异常,比如a方法声明了异常,调用它的b方法不解决异常,可以继续声明a的异常,由于这些方法最后都会回到main方法,所以如果这些方法都不解决异常,就交给虚拟机处理 main方法声明的异常由Java虚拟机处理

使用throw抛出异常

写法见以下代码

1
throw new 某类型Exception("异常信息");//当使用throw显式抛出异常,必须对异常处理,或throws声明异常
throw throws
生成并抛出异常 声明方法内抛出了异常
位于方法体内部,可作为单独语句使用 必须跟在方法参数列表后面,不能单独使用
抛出一个异常对象,且只能是一个 声明抛出异常类型,可以用来一次声明多个异常类型

注意

  • 如果在try和catch中遇到return,先执行finally,再执行return
  • try\catch\finally可以任意组合, 但必须有try,catch和finally至少出现一个
  • 如果方法内产生异常却不在方法内处理 有throw但没有catch,就必须使用throws声明该异常

异常体系结构

我们注意到,Exception对象的直接父类是Throwable类,而Throwable类除了Exception类这个直接子类外,还有一个直接子类叫Error。Error为仅靠程序本身无法恢复的严重错误,代表Java虚拟机的底层问题(比如AWTError (发生严重的Abstract Window Toolkit错误时抛出)、线程意外终止ThreadDeath等、内存溢出OutOfMemoryError)而Exception为由Java应用程序抛出和处理的非严重错误。而Exception又进一步可细分为Checked异常和运行时异常RuntimeException,Checked异常在编译时会被检查出来,程序必须处理该类异常,如ClassNotFoundException、ClassCastException等。RuntimeException表示该异常为运行时可能出现的异常,在编译时不会检查的异常,不要求程序必须做出处理,如ArithmeticException算术异常、调用null对象异常NullPointerException等,这些异常一般是由程序的逻辑错误引起的。

自定义异常

异常链与异常处理原则

抽象类和接口

前言

本文为华为开发者学堂-面向对象编程的课程笔记,仅供个人学习使用。

抽象方法和抽象类(欧内的手方法和奥利安费类

抽象方法

书接上文

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class Master{//主人类写法
public void cure(Pet pet){//父类作为方法的形参
if(pet.health<50){
pet.cure();
}
}
}
public class Pet{//父类写法
public int health;
public String name;
public String sex;
public void cure(){
//这里不要写属性的修改,因为要修改的是子类的属性(我好像在说废话x)
}
}
public class Cat extends Pet{//子类写法
public void cure(){
System.out.println("打针");
this.heatlh=60;
}
}

我们注意到,在上面Pet类里的cure方法内没有具体内容,而它的实现在子类里,此时我们就可以将它写成public abstract void cure();,也就是将其写成一个抽象方法。而抽象方法所在的类也要通过public abstract class Pet的改写来转变为抽象类

抽象类

当声明这个类的一个对象是没有意义的时候,就可以将这个类写为抽象类,抽象类不能被实例化

需要注意

  • 抽象类不能被实例化(不存在抽象构造方法),但可以创建一个抽象类的引用变量指向非抽象的子类实例
  • 如果子类没有实现父类的所有抽象方法,子类必须被定义为抽象类
  • 抽象方法没有方法体
  • 抽象方法必须在抽象类里,而抽象类里可以没有抽象方法。
  • 不存在抽象静态方法
  • 抽象类可以有非抽象构造方法,因为构造非抽象子类实例时可能需要用到,这样可以节省代码
  • 抽象方法必须在子类中被实现除非子类是抽象类

    小结

  • 当子类们既有共性方法又有各自特性方法的时候,我们可以通过声明抽象方法和抽象类来简化代码、方便调用。

接口

我们为什么需要接口

我们知道一个类只能有一个父类,而当一个类需要继承多组相互之间不相关的方法时,这些方法都塞在一个父类里或者多个间接父类里显然不合理,因此我们需要多个接口来存放和管理各组方法。

什么是接口

  • 概念性的接口指系统对外提供的所有服务。
  • interface定义的接口叫接口类型,但是接口不是类
  • JDK8之前的接口特性
    • 接口中的变量默认都是静态常量,必须显式初始化
    • 接口中所有方法默认都是抽象方法
    • 接口没有构造方法,不可以被实例化,但可以被实现
    • 通过implements关键字声明实现类,一个实现类可以实现多个接口
    • 实现类必须实现接口的所有方法,除非实现类也是一个抽象类
  • JDK8新增接口特性1:接口内可以有默认方法
    • 通过default关键字来声明默认方法,默认方法的用处在于简化代码,降低实现类和接口的耦合度,提升代码可维护性
    • 默认方法可以被继承,通过实例调用
    • 如果一个类实现了多个接口,多个接口都定义了多个同样的默认方法
      • 实现方案1:实现类需要覆盖重写接口中的默认方法不然会报错
      • 实现方案2:可以使用this来调用指定接口的默认方法
    • 如果一个类继承了一个抽象类,实现了一个接口,抽象类和接口存在相同的方法
      • 采取类优先的原则,有限继承抽象类的方法
  • JDK8新增接口特性2:**接口内可以声明(并且可以提供实现)静态方法了
    • 回顾:静态方法可以直接用类名调用(不用专门new一个对象了)
    • 接口中的静态方法必须是public的,public修饰符可以省略,static修饰符不能省略
    • 静态方法不能被继承及重写,所以只能被具体所在的接口调用
    • 接口中可以有多个静态方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/*接口格式
访问修饰符 interface 接口名称 extends 其他接口名(如果有的话){
声明变量
声明方法
}*/
//接口示例
public interface Interface1{
public static final double PI =3.14;//在接口里,你写个double PI =3.14 也等同于左边的写法
public void m2();//等同于 public abstract void m2();
default void m3(){
System.out.println("已调用接口Interface1中的默认方法m3");
}
}
//实现类示例
public class Implementation implements Interface1{//多个接口间用逗号隔开
public void m2(){
System.out.println("实现用接口Interface1中的默认方法m2");
}
public void usem3(){
this.m3();
}
}

抽象类和接口的比较

  • 相同点
    • 代表系统的抽象层
    • 都不能被实例化
    • 都能包含抽象方法
  • 不同点
    • 在抽象类中可以为部分普通方法提供默认实现,而接口在JDK8之前只能包含抽象方法,JDK8之后接口可包含默认方法
    • 一个类只能继承一个直接的父类,但可以实现多个接口

方法重写与多态

前言

本文为华为开发者学堂-面向对象编程的课程笔记,仅供个人学习使用。

方法重写

我们为什么需要方法重写?

有一个父类/超类叫pet,它有两个子类dog和cat,dog和cat有共同的属性名字和性别,有共同的输入和输出信息方法setInfo()和showInfo(),将这些属性和方法都写在父类里。现在有新的要求,dog增加了一个属性是品种,cat增加了一个属性是体重,这时候发现方法原来的写法不能同时满足两个子类不同属性的输出,此时我们提出三种解决方案:

  1. 删除父类的方法,在子类内分别写方法并调用:这种方法简单粗暴,但是一旦像这样的同时具有相同和不同属性与方法的子类增多,会使得代码有很多重复的部分,增大了工作量。
  2. 保留父类的方法,同时将不同的部分分别写入子类专属的方法内:这种方法较上一种的工作量减少了,但是在调用的时候会变得麻烦,既然都是输入输出信息的功能,为什么不让它们名称相同呢?
  3. 子类重写父类方法:
    • 子类根据需求对从父类继承的方法进行重新编写
    • 重写时,可以用super.方法的方式保留父类的方法
    • 构造方法不能被重写

方法重写的规则

  • 方法名相同
  • 参数列表相同
  • 返回值类型相同或是其子类
  • 访问权限不能严于父类
  • 父类的私有方法不能被子类覆盖
  • 子类方法不能抛出比父类方法更多的异常
  • 父类的静态方法不能被子类覆盖为非静态方法,父类的非静态方法也不能被子类覆盖为静态方法
  • 由于super不能在静态方法中使用,因此子类可以定义与父类同名的静态方法,以便在子类中隐藏父类的静态方法

代码示例(因仅供个人学习用,因此略写了测试类,且由于两个子类大同小异,故只给出cat类(说什么我都开摆!

父类写法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Pet {//父类
//按照方法1的写法,这里可以啥都没有x
public String name;//方法2中这里要保留
public String sex;
//方法3写法(方法2中父类的写法和方法3一致,故略)
public void setInfo(String name, String sex){
this.name=name;
this.sex=sex;
}
public void showInfo(){
System.out.println("宠物的名字是:"+name+",宠物的性别是:"+sex);
}
}

子类写法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public class Cat extends Pet{//子类
private float weight;//体重
private String name;//名字
private String sex;//性别
/*方法1写法
public void setInfo(String name,String sex, float weight){
this.name = name;//这里实际上略写了name和sex的声明,这两个属性的声明可以在父类中以public关键字做保留,也可以在子类中写
this.sex = sex;
this.weight = weight;
}
public void showInfo(){
System.out.println("宠物的名字是:"+name+",宠物的性别是:"+sex+",猫的体重是"+weight);
}
*/
/*方法2写法
public void setInfo(String name,String sex, float weight){
this.name = name;
this.sex = sex;
this.weight = weight;
}
public void showCatInfo(){//注意此处的改名
showInfo();
System.out.println("猫的体重是"+weight);
}
*/
//方法3写法

public void showInfo(){
super.showInfo();
System.out.println("猫的体重是"+weight+"kg");
}
}

Super

  • super可以用来访问父类的非私有(private)成员
  • 静态方法中不能出现super
  • 当子类中定义了和父类同名的成员时,super可以使被屏蔽的成员可见
  • super只能出现在子类的方法和构造方法中
  • super调用父类构造方法时,只能是super所在方法的第一句
  • super可以用于调用继承关系中最近的父类/间接父类的成员
    • 当子类、父类、间接父类中都有同名的成员时(子类重写/覆盖父类,父类重写/覆盖间接父类)时,子类中使用super只能访问父类的成员。
    • 当子类和间接父类中有同名成员时,子类中使用super可以访问继承关系中最近的间接父类成员。
1
2
3
4
5
6
7
//访问父类方法
super.print();
//访问父类属性
super.name;
//访问父类构造方法
super();
super(name)

super和this比较

区别 this super
访问属性 访问本类属性,如果没有则从父类找 访问父类属性
访问普通方法 访问本类普通方法,如果没有则从父类找 访问父类普通方法
访问构造方法 调用本类构造,放在构造方法首行 调用父类构造,放在子类构造方法首行

继承条件下的构造方法

  • 当子类构造方法没有通过super显式调用父类的带参构造方法,也没有通过this显式调用自身其他构造方法时,系统默认调用父类的无参构造方法
  • 相对的,当子类构造方法通过super显式调用父类的带参构造方法时,系统执行父类的带参构造方法而不执行父类的无参构造方法
  • 子类构造方法通过this显式调用自身的其他构造方法,在相应构造方法中应用上述两条规则
  • 注意,子类的构造方法在执行时,无论是否有显式给出,父类的构造方法在逻辑顺序上永远是第一个执行的

Object类

Object类是什么?

  • Object类是所有类的直接或间接父类,而且是继承关系最远的那个直接或间接父类

    Object类有什么?

  • 自己找个IDE(比如myeclipse),新建类然后写个this,Object类里的东西就在提示弹窗里显示出来了
  • Object类被子类经常重写的方法
    • toString(): 返回当前对象本身的有关信息,按字符串对象返回
    • equals(): 比较两个对象是否是同一个对象,是则返回true
    • hashCode(): 返回该对象的哈希值
    • getClass(): 获取当前对象所属的类信息,返回Class对象

此处的小补充

1
2
3
4
5
6
7
//equals函数判断是否是一个对象的依据是看两个对象是否占用同一处内存
//这里假设有一个Student类
Student s1 = new Student();
Student s2 = new Student();
Student s3 = s1;
System.out.println(s1.equals(s3));//结果为true
System.out.println(s1.equals(s2));//结果为false,因为二者成员虽然一样,但在不占用同一处内存。

重写Object类的方法(此处以重写equals方法为例)

我们接着上面的问题来,如果两个学生类的所有属性都一样,按理说它们指的就是一个人,但按照equals()的原理却不能认为两个对象相同,即当认为属性相同就是同一对象时,就有了重写equals()的需要。
代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//如果两个学生的属性(此处为姓名name和学号sid)相同,就认为是同一个学生对象。
public boolean equals(Object obj){//注意,此处是Student的equals方法。
//如果占用的是同一处内存
if(this == obj){
return true;
}
//此处应用instanceof运算符,“对象a instanceof 类型b”的意思是判断a是否为b的实例
elif(!(obj instance of Student)){//如果对象不是Student类型
return false;
}
Student s = (Student)Obj;//将Obj强制转换为student类型,这里实际上也可以省去这一步,但是这样更保险一些。
if (this.name==s.name&&this.sid==s.sid)//这里判断name是否相同还有一种写法就是“this.name.equals(s.name)”,由此可见Java.lang.String已经重写过一遍equals方法,使其可以用于判断字符串是否相同。
return true;
else
return false;
}

多态

我们为什么需要多态?

接着上面说过的dog、cat和pet类继续讲,现在我们设定pet类增加了健康值health这个属性,当健康值小于50时,认定宠物生病了,需要治疗,我们将治疗方法cure()放在新建的主人类master里,治疗方法的内容是显示治疗方案和修改宠物实例的health值为60。而不同的宠物需要不同的治疗方式,我们设定治疗猫时需要显示“打针”,治疗狗时需要显示“吃药”。我们可以使用方法重载来实现,主人类的代码此时如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Master{
public void cure(Cat cat){
if(cat.health<50){
System.out.println("打针");
cat.health=60;
}
}
public void cure(Dog dog){
if(dog.health<50){
System.out.println("吃药");
dog.health=60
}
}
}

但当宠物的种类变多时,这种写法会需要频繁修改,更不用说如果不止是主人类需要有这个cure方法,还有其他和主人类类似的类需要有这个cure方法时,就会导致代码臃肿、可扩展性、可维护性差,因此我们需要多态来优化。

什么是多态?

多态:同一个引用类型,使用不同的实例而执行不同的操作
使用父类作为方法的形参,是Java中实现和使用多态的主要方式。
使用父类作为方法的返回值,也是Java中实现和使用多态的主要方式。
我们接着来看刚才的例子。我们的优化思路是将治疗方法cure移到父类pet内,pet的各个子类重写父类的pet方法,此时主人类、父类、子类的代码简化如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class Master{//主人类写法
public void cure(Pet pet){//父类作为方法的形参
if(pet.health<50){
pet.cure();
}
}
}
public class Pet{//父类写法
public int health;
public String name;
public String sex;
public void cure(){
//这里不要写属性的修改,因为修改的是子类的属性(我好像在说废话x)
}
}
public class Cat extends Pet{//子类写法
public void cure(){
System.out.println("打针");
this.heatlh=60;
}
}

这里附上一个父类作为方法的返回值的多态用法,假设我们要送动物给别人。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Master{//主人类写法
public Pet sendPet(int type){//以父类作为返回对象,也是多态的一种用法
Pet pet = null;
switch(type){
case 1:
Pet pet=new Cat();
break;
case 2:
Pet pet=new Dog();
break;
default:
System.out.println("私密马赛!没有这种宠物");
break;
}
return pet;
}
}

注意,这时你再构建对象,你就得写成Pet xx = new Xx(),即向上转型这里和以前的写法规定不一样了。而当master的cure函数收到Pet类型的对象时,系统会找到这个对象指向的具体的类型Xx,也就是实际上在调用时将其视作Xx类型的对象

关于向上(向下)转型

上文中我们把父类类型引用变量指向子类对象,自动进行类型转换的写法称为向上转型,自然地,我们也将父类类型引用变量强制转换为子类类型引用变量的写法称为向下转型

我们为什么需要转型

当我们需要以多态写法(我个人将多态理解成一种写法)去简化调用这些子类的方法时,我们需要将参数表里传入的类型向上转型成子类共同继承的父类类型来使方法在具备简洁的方法体的同时可以灵活调用各个子类重写的父类方法,而当我们需要调用子类的特有方法时,由于父类对象不能调用子类特有的方法就需要将其强制转换回子类,即向下转型,从而实现调用。

转型需要注意的地方

  • 向上转型后只能调用子类覆盖或继承父类的方法,不能调用子类特有的方法
  • 在向下转型的过程中如果没有转换成真实子类类型,会出现类型转换异常,来看下面的代码。
1
2
3
4
5
6
7
public class Test(){//测试类
public static void main(String[]args){
Pet dog = new Dog();//先来个向上转型
Cat cat = (Cat) dog;//再来个向下转型
cat.meow();//让猫(实际上是“变成猫”的狗)调用喵喵叫方法(狗肯定不会喵喵叫啊所以是猫的特有方法)
}
}

上面这段代码在写的时候IDE不会给你报错,也就是没有语法问题。但当你编译它的时候,IDE会告诉你存在编译错误(至少我的Myeclipse是这样)java.lang.ClassCastException:Dog cannot be cast to Cat类型转换异常:狗变不成猫!),所以注意,向下转型时如果没有转化为真实的子类类型,会触发类型转换异常。
如果想要避免类型转换异常的出现,我们可以借助instanceof来进行辅助判断,来看下面的代码。

1
2
3
4
5
6
7
8
9
10
11
public class Test(){//测试类
public static void main(String[]args){
Pet dog = new Dog();//先来个向上转型
if (dog instanceof Dog){
dog.bark();//汪汪汪
}
elif(dog instanceof Cat){
cat.meow();//喵喵喵
}
}
}
  • 注意,使用instanceof时,对象的类型必须和instanceof后面的类在继承上有上下级关系

计网课程笔记1

前言

课程链接
本文仅供个人预习和知识点记录你这不就是抄了一遍PPT吗用。


1.1 计算机网络在信息时代中的作用(略)(原课程下置顶评论内有完整课程PPT)


1.2 计算机网络、互联网的定义与发展

1.2.1互联网·计算机网络·互连网

  • 互联网(Internet):覆盖全球的计算机网络,采用TCP/IP协议
  • 计算机网络(computer network):由若干结点和连接这些结点(node)的链路组成
  • 互连网(internet):泛指通过路由器将各个计算机网络连接起来形成的更大的计算机网络

    关于“云”这个图形

  • 当使用一朵云来表示网络时,可能有两种不同的情况:
    • 云表示的网络已经包含了和网络相连的计算机
    • 云表示的网络里剩下许多路由器和连接这些路由器的链路(link),把有关的计算机画在云的外面,将网络相连的计算机称为主机(host)

1.2.2计算机网络发展的三个阶段

  • 第一阶段:军用网络ARPANET
  • 第二阶段:三级结构互联网:主干网-地区网-园区网
  • 第三阶段:多层次互联网服务提供者(ISP)结构互联网

1.2.3互联网的标准化

**所有互联网标准都以RFC形式在互联网上发表

  • 互联网草案(Internet Draft):有效期只有六个月,在这个阶段还不是RFC文档
  • 建议标准(Proposed Standard):从这个阶段的开始就是RFC文档
  • 互联网标准 (Internet Standard):形成正式标准后,每个标准就分配到一个编号。一个标准可以和多个RFC文档关联

1.3互联网的组成

从互联网的工作方式上看,可以划分为两大块:边缘部分核心部分

  • 边缘部分:由所有连接在互联网上的主机组成,这部分是用户直接使用的,用于通信(数据传输)和资源共享
  • 核心部分:由大量网络和连接这些网络的路由器组成,这部分是为边缘部分提供服务的(提供连通性和交换)

1.3.1互联网的边缘部分

构成互联网边缘部分的主机称为端系统(end system),端系统可以有很大的差别(功能、所有者、性能……)

端系统间通信的含义

端系统间的通信,实际上是指运行在主机A上的某个程序 (从占用计算机资源的角度划分为进程)与运行在主机B上的某个程序(进程)进行通信

端系统间的两种通信方式

端系统之间的通信方式通常可划分为两大类:

  • 客户-服务器方式(C/S方式) Client/Server

    • 客户和服务器都是指通信中所涉及的两个应用进程
    • C/S方式所描述的是进程之间服务和被服务的关系
    • 客户是服务的请求方,服务器是服务的提供方
    • 客户软件的特点
      • 被客户调用后运行,在打算通信时主动向远地服务器发起服务请求。因此客户程序必须知道服务器程序的地址
      • 不需要很特殊的硬件和很复杂的操作系统
    • 服务器软件的特点
      • 一种专门用来提供某种服务的程序,可同时处理多个远地或本地客户的请求
      • 系统启动后即自动调用并一直不断地运行着,被动地等待并接受来自各地的客户的服务请求。因此,服务器程序不需要知道客户程序的地址
      • 客户和服务器的通信关系建立后,通信服务是双向的,客户和服务器都可发送和接收数据
      • 一般需要强大的硬件和高级的操作系统支持
  • 对等方式(P2P方式) Peer to Peer(点到点/端对端)

    • 对等链接是指两个主机在通信时并不区分哪一个是服务请求方还是服务提供方
    • 只要两个主机都运行了对等连接软件,就可以进行平等的、对等连接通信
    • 双方都可以下载对方已经存储在硬盘内的资料

接入网络

  • 接入网:将端系统连接到其边缘路由器的物理链路,是用户连接到网络的基础设施
  • 边缘路由器:端系统到任何其他远程端系统的路径上的第一台路由器
  • 将端系统连接到网络边缘路由器的粗糙分类:
    • 家庭接入网络(点对点接入)
      • 方式1:使用传统的电话线路连接本地中心局,数据通信和电话不能同时使用 (拨号上网)
      • 方式2:使用传统的电话线路连接本地中心局,数据通信和电话采用频分多路复用技术
        • 有多种传输速率
        • 住宅和中心局距离不超过8——10英里
        • 采用非对称数字用户线路模式(ADSL) (下行需要大带宽支持,上行只需小量带宽),ASDL调制解调器始终和互联网连接,省去拨号上网、在电话线上产生三个通道 (上行、下行、电话)三个通道可以同时工作
      • 方式3:使用线缆调制解调器、混合光纤同轴电缆HFC
        • 通过一个以太网端口与家庭PC连接
        • 光节点发送的分组经下行信道传输到每个家庭,若多个用户同时下载则会导致接收速率下降
        • 每个家庭发送的分组经上行信道向光节点传输,几个用户同时发送分组将会冲突,需要多路访问协议协调
      • 方式4:使用光纤到户FTTH
        • 从本地局到每个家庭都提供一条光纤路径
        • 从中心局出来的每根光纤由多个家庭共享,在临近家庭的位置通过光纤分配器给每个家庭提供一根光纤
    • 企业/家庭接入网络、广域无线接入网络:见1.5.2

1.3.2互联网的核心部分

  • 网络核心部分是互联网中最复杂的部分
  • 网络中的核心部分要向网络边缘中的大量主机提供连通性,使得边缘部分中的任何一个主机都能够向其他主机通信
  • 在网络核心部分起特殊作用的是路由器(router),路由器是实现分组交换的关键构件,其任务是转发收到的分组,这是网络核心部分最重要的功能

为了理解分组交换,首先要看电路交换

电路交换的主要特点

如果N台电话要两两相连,那么需要N(N-1)/2对电话线,当N很大时,电话线的数量与N²近似成正比,这对不利于电话网的建设。因此当电话机的数量增多时,就要使用交换机来完成全网的交换任务。而交换机所采用的交换方式就是电路交换

  • 在这里,交换的含义就是转接,将两条电话线连通起来。
  • 从通信资源的分配角度来看,交换就是依照某种方式动态地分配传输线路的资源
  • 电路交换的特点
    • 电路交换必定是面向连接(必须得接通才能连接)
    • 电路交换分为三个阶段:
      • 建立连接:建立一条专用的物理通路,以保证双方通话所需的通信资源在通信时不会被其他用户占用
      • 通信:双方交流信息的过程
      • 释放连接: 释放占用的所有通信资源
  • 电路交换的优点:通信稳定
  • 电路交换用于计算机网络时的缺点:计算机数据具有突发性(不是一直都在传数据),导致在传送计算机数据时通信线路的利用率很低,产生资源的浪费

分组交换的主要特点

  • 分组交换采用存储转发技术
  • 在发送端,先把较长的报文划分成较短的、固定长度的数据段
  • 每一个数据段前面添加上首部构成分组
  • 分组交换传输单元(此处假定在传输过程中数据没有损失)
    • 分组交换网以分组作为数据传输单元,每一个分组的首部都含有目的地址和源地址等控制信息,分组交换网中的结点交换机根据收到的分组首部地址中的地质信息,把分组转发到下一个结点交换机
    • 每个分组在互联网中独立地选择传输路径
    • 依次把各分组发送到接收端
    • 接收端收到分组后剥去首部还原成数据,再恢复成原来的报文
  • 分组交换的优点
    • 高效:在分组传输的过程中动态分配传输带宽,对通信链路逐段占用
    • 灵活:为每一个分组独立地选择最合适的转发路由
    • 迅速:以分组为传送单位,可以不先建立连接就能向其他主机发送分组
    • 可靠:保证可靠性的网络协议;分布式多路由组成的交换网使得网络有很好的的生存性
  • 分组交换的缺点
    • 分组在各节点存储转发需要排队,造成一定的时延ping
    • 分组必须携带的首部造成一定的开销

互联网核心的组成

  • 互联网的核心部分由许多网络和将它们连接起来的路由器组成,而主机(端系统)处在互联网的边缘部分
  • 互联网核心部分中的路由器之间一般都用高速链路相连接,而在网络边缘的主机接入到核心部分通常以相对较低速率的链路相连接
  • 主机的用途是为用户进行信息处理,并和其它主机通过网络交换信息 (发送分组,接收分组) 。路由器的用途是用来转发分组,即进行分组交接,先存储收到的数据,再决定要转发到哪里

路由器

  • 在路由器中的输入和输出端口之间没有直接连线
  • 路由器处理分组的过程是:
    • 把收到的分组先放入缓存
    • 查找转发表,找出到某个目的地址应该从哪个端口转发
    • 把分组送到适当的端口转发出去

电路交换、报文交换、分组交换的不同(个人理解)

  • 电路交换需要等待连接建立后才能传递信息,有一定的时间的浪费,且发送信息期间链路均被占用,成本高
  • 报文交换不需要等待连接建立,对每个链路的占用时长降低,因此成本低,但因为结点之间的传送存在次序,必须要等上一级结点传送完毕才能传给下一结点,导致用时长
  • 分组交换将报文分成多个分组,压缩了传送时间且具有报文交换的优点。

1.4 计算机网络在我国的发展(略)


1.5 计算机网络的类别

1.5.1 计算机网络的定义(计算机网络的精确定义并未统一)

  • 课程给出的定义:计算机网络主要是由一些通用的、可编程的硬件 (表明这种硬件一定含有CPU)互连而成的,而这些硬件并非专门用来实现某一特定目的。这些可编程的硬件能够用来传送多种不同类型的数据,并能支持广泛的和日益增长的应用。

1.5.2几种不同类别的网络

  • 计算机网络有多种类别。类型包括:
    • 从网路的作用范围进行分类

      • 广域网WAN:作用范围几十到几千公里
      • 城域网MAN;作用范围5~50公里
      • 局域网LAN/园区网:局限在较小范围(如1公里左右)
      • 个人局域网PAN:范围很小,大约在10米左右
    • 从网络的使用者进行分类

      • 公用网:按规定缴纳费用的人都可以使用的网络
      • 专用网:为特殊业务工作的需要而建造的网络
    • 用来把用户接入到互联网的网络

      • 接入网AN:又称本地接入网或居民接入网
      • 接入网是一类比较特殊的计算机网络,用于将用户接入互联网。
      • 接入网本身既不属于互联网的核心部分,也不属于互联网的边缘部分,由端系统到另一个端系统的路径中与第一个路由器间的物理链路所构成。从覆盖的范围看,很多接入网属于局域网,从作用上看,接入网只是起到让用户能够与互联网连接的作用。

1.6计算机网络的性能,是什么?如何衡量?

1.6.1计算机网络的性能指标

  • 速率

    • 计算机数据量/信息量单位比特bit
    • 速率指的是数据的传送速率,也称为数据率比特率
    • 速率的单位是bit/s,更大的单位有kbit/s,Mbit/s,Gbit/s等等。需要注意的是,1kb=1024b,1kb/s=1000bit/s,其余以此类推。
  • 带宽

    • 带宽本来是指信号所具有的频带宽度,单位是Hz
    • 在计算机网络中,带宽用来表示网络中某信道传送数据的能力,表示在单位时间内网络中的某通道所能通过的最高数据率,因此单位和速率一样是bit/s
    • 在时间轴上信号的宽度随带宽的增大而变窄
  • 吞吐量

    • 吞吐量表示在单位时间内通过某个网络/通道/接口的数据量
    • 吞吐量常用于对显示世界中网络的测量,以便知道有多少数据能够通过网络
    • 吞吐量受网络带宽/网络额定速率的限制
  • 时延/延迟ptsd犯了

    • 延迟是指数据从网络链路一段传送到另一端所需要的的时间
    • 网络延迟由以下几个不同的部分组成:
      • 发送延迟 = 数据帧长度/发送速率
      • 传播延迟:电磁波在信道中传播一定的距离而花费的时间。可知传播延迟和发送延迟有本质上的不同。传播延迟==通道的物理长度/信号的传播速度
      • 处理延迟:主机或路由器收到分组时,为处理分组(分析首部、提取数据、差错检验、查找路由)所花费的时间
      • 排队延迟:分组在路由器输入输出队列中排队等待处理所需时间取决于网络中当时的通讯录
    • 延迟=发送延迟+传播延迟+处理延迟+排队延迟
  • 时延带宽积

    • 链路的时延带宽积又称以比特为单位的链路长度
    • 时延带宽积=传播时延x带宽
  • 往返时间RTT

    • 往返时间表示从发送方发送数据开始到发送方收到来自接收方的确认总共经历的时间
    • 往返时间=各中间结点的处理延迟和排队延迟+传播延迟+发送延迟
  • 利用率

    • 分为信道利用率网络利用率
    • 信道利用率:指出某信道有百分之几的时间是有数据通过的。
    • 网络利用率:全网络的信道利用率的加权平均值
    • 信道利用率并非越高越好,当某信道的利用率增大时,该信道引起的时延也将急剧增加,若令D0为网络空闲时的延迟,D表示网络当前的延迟,U表示网络的利用率,则在适当的假定条件下,可以用公式D=D0/(1-U)表示D和D0的关系

1.6.2计算机网络的非性能特征

  • 费用
  • 质量
  • 标准化
  • 可靠性
  • 可扩展性和可升级性
  • 易于管理和维护

1.7计算机网络的体系结构

1.7.1计算机网络体系结构的形成

  • 相互通讯的两个计算机系统必须高度协调工作,而这种协调是相当复杂的
  • 分层可将庞大而复杂的问题转化为若干较小的局部问题,化繁为简,易于处理。
  • 在形成统一标准之前,各种体系结构的计算机网络之间很难相互连通,为了解决该问题,ISO于1977年提出了标准框架开放系统互连基本参考模型,简称OSI,但OSI在市场化方面失败了。
  • 目前的两种国际标准(事实意义上)为TCP\IP

1.7.2协议与划分层次

  • 计算机网络中的数据交换必须遵守实现约定的规则,这些规则明确规定了所交换的数据的格式以及有关的同步问题
  • 网络协议是为进行网络中的数据交换而建立的规则、标准或约定
  • 网络协议的三个组成要素
    • 语法:报文格式/数据与控制信息的结构或格式
    • 语义:每个字段的含义/需要发出何种控制信息。完成何种动作以及做出何种响应
    • 同步:报文传输的先后次序/事件实现顺序的详细说明
  • 协议的两种形式:文字描述、程序代码
  • 分层:将计算机数据的传送划分为彼此之间有联系但功能上相互独立的多个层次进行。
  • 分层的好处和缺点
    • 好处
      • 各层之间相互独立
      • 灵活性好
      • 结构上可分割
      • 易于实现和维护
      • 能促进标准化工作
    • 缺点
      • 效率降低
      • 有些功能会在不同的层次中重复出现,因而产生额外开销
    • 因此层数的多少要适当,层数太少会使得每一层的协议太过复杂,而层数太多,又会在描述和综合各层功能的系统工程任务时遇到较多的困难

如何恰当分层?

  • 各层完成的主要功能
    • 差错控制:使相应层次对等方的通信更加可靠
    • 流量控制:发送端的发送速率必须使接收端来得及接收,不要太快
    • 分段和重装:发送端将要发送的数据块划分为更小的单位,在接收端将其还原
    • 复用和分用:发送端几个高层会话复用一条底层的连接,在接收端再进行分用
    • 连接建立和释放:交换数据前先建立一条逻辑连接,数据传送结束后再释放连接

计算机网络的体系结构

  • 计算机网络的体系结构是关于网络的各层及其协议的集合
  • 体系结构就是这个计算机网络及其部件所应完成的功能的精确定义
  • 实现是遵循这种体系结构的前提下用何种硬件或软件完成这些功能的问题

1.7.3具有五层协议的体系结构

  • OSI的七层体系结构虽然概念清楚、理论较为完整,但它既复杂又不实用。
  • TCP/IP 是四层体系结构:应用层、运输层、网际层和网络接口层,但最下面的网络接口层并没有具体内容。
  • 因此采取折中的办法,即综合OSI和TCP/IP的优点,采用一种五层协议的体系结构:应用层(对应OSI的应用层+表示层+会话层)、运输层、网络层、数据链路层、物理层

    主机1向主机2通过五层协议体系结构发送数据的全过程

  • 应用进程数据先传送到应用层,加上应用层首部,成为应用层PDU(OSI把对等层次之间传送的数据单位称为该层的协议数据单元)
  • 发送
    • 应用层PDU再传送到运输层,加上运输层首部成为运输层报文
    • 运输层报文再传送到网络层,加上网络层首部成为IP数据报/分组
    • IP数据报再传送到数据链路层,加上链路层首部和尾部,成为数据链路层帧
    • 数据链路层帧再传送到物理层,物理层把比特流传送到物理媒体
  • 接收
    • 物理层接收到比特流,上交给数据链路层
    • 数据链流层剥去帧首部和尾部,取出数据部分上交给网络层
    • 网络层剥去首部,取出数据部分上交给运输层
    • 运输层剥去首部,取出数据部分上交给应用层
    • 应用层剥去首部,取出应用程序数据上交给应用进程,传送结束
  • 任何两个同样的层次把数据通过水平虚线 (包含两个层次下面的所有部分)直接传递给对方,这就是所谓的对等层之间的通信
  • 各层协议实际上就是在各个对等层之间传递数据时的各项规定

1.7.4 实体、协议、服务和服务访问点

  • 实体:表示任何可发送或接收信息的硬件或软件进程
  • 协议:控制两个对等实体进行通信的规则的集合。在协议的控制下,两个对等实体间的通信使得本层能够向上一层提供服务。要实现本层协议,还需要使用下层所提供的服务
  • 注意协议和服务的区别,协议是水平的,即协议是控制对等实体之间通信的规则,服务是垂直的,即服务是由下层向上层通过层间接口提供的。本层的服务用户只能看见服务而无法看见下面的协议。
  • 协议必须把所有不利的事件事先都估计到,不能假定一切都是正常的、非常理想的。看一个计算机网络协议是否正确,不能光看在正常情况下是否正确,还必须非常仔细地检查这个协议能否应对各种异常情况

测试文档

这是一个一级标题

内容

字体

字体加粗
字体倾斜
字体加粗倾斜
字体加删除线

这是嵌套

这是嵌套

这是嵌套

这是一个六级标题

分割线


图片

添加涩图测试


超链接

超链接测试
b站主页


代码和代码块

代码

1
system.out.println("hello world!");

代码块

1
2
3
for(i=0;i<=9;i++){
system.out.println("当前数字是"+i);
}

表格

乘数 乘数
2 2 4
3 3 9
1 2 2

列表

无序列表


有序列表

  1. 列表内容
  2. 列表内容
  3. 列表内容

列表嵌套

  1. 列表内容
    • 分支列表内容
    • 分支列表内容
      +分支列表内容
  2. 列表内容

  • Copyrights © 2022 Daniel Qi
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信