网络编程基础01:网络编程概述、IP和端口

网络编程基础01:网络编程概述、IP和端口

网络编程概述

计算机网络(连接分散计算机设备以实现信息传递的系统)

计算机网络是指将地理位置不同 的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件网络通信协议 的管理和协调下,实现资源共享和信息传递 的计算机系统。

网络编程的目的

  • 就是用来实现网络互连的不同计算机上运行的程序间可以进行数据交换
  • java.net 包中 J2SE 的 API 包含有类和接口,它们提供底层次的通信细节。你可以直接使用这些类和接口,来专注于解决问题,而不用关注通信细节。
  • 有人说,20世纪最伟大的发明不是计算机,而是计算机网络。
  • 还有人说,如果你买了计算机而没有联网,就等于买了电话机而没有接电话线一样。

网络通信的两个要素

  • 通信双方地址:

    • ip
    • 端口号
  • 网络通信协议

    TCP/IP参考模型:

    • OSI七层网络模型和TCP/IP五层协议对应关系:

    • 每层的功能:

    • 每层的协议:

      应用层协议

      1. 超文本传输协议(HTTP):万维网的基本协议;
      2. 文件传输(TFTP简单文件传输协议);
      3. 远程登录(Telnet),提供远程访问其它主机功能, 它允许用户登录internet主机,并在这台主机上执行命令;
      4. 网络管理(SNMP简单网络管理协议),该协议提供了监控网络设备的方法,以及配置管理,统计信息收集,性能管理及安全管理等;
      5. 域名系统(DNS),该系统用于在internet中将域名及其公共广播的网络节点转换成IP地址。

      传输层协议

      1. TCP(TransmissionControl Protocol,传输控制协议);
      2. UDP(UserData Protocol,用户数据报协议)

      网络层协议

      1. Internet协议(IP);
      2. Internet控制信息协议(ICMP);
      3. 地址解析协议(ARP);
      4. 反向地址解析协议(RARP)。

      传输层协议TCP(传输控制协议)和UDP(用户数据报协议)的区别:安全方面的区别、传播速度的区别、连接对象数量的区别。安全方面的区别:tcp的安全性没有udp的安全性高,并且udp的漏洞比较少,不容易被一些不法分子利用;传播速度的区别:udp的传送速度也比tcp的快。因为tcp在传送的时候要先建立连接,建立连接的时候是比较耗时的,而且在传送数据的时候还要确认一些东西,而udp无连接传送数据的;连接对象数量的区别:tcp是一对一的连接,而udp是一对多个或多对多个连接的。

      TCP三次握手:

      第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SENT状态,等待服务器确认;SYN:同步序列编号(Synchronize Sequence Numbers)。

      第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;

      第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。

      TCP四次挥手过程理解:

      第一次挥手:当主机A完成数据传输后,将控制位FIN置1,提出停止TCP连接的请求;

      第二次挥手:主机B收到FIN后对其作出响应,确认这一方向上的TCP连接将关闭,将ACK置1;

      第三次挥手:由B 端再提出反方向的关闭请求,将FIN置1 ;

      第四次挥手:主机A对主机B的请求进行确认,将ACK置1,双方向的关闭结束.。

      详情:

      1)客户端进程发出连接释放报文,并且停止发送数据。释放数据报文首部,FIN=1,其序列号为seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1),此时,客户端进入FIN-WAIT-1(终止等待1)状态。 TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。

      2)服务器收到连接释放报文,发出确认报文,ACK=1,ack=u+1,并且带上自己的序列号seq=v,此时,服务端就进入了CLOSE-WAIT(关闭等待)状态。TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。

      3)客户端收到服务器的确认请求后,此时,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。

      4)服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=u+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w,此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。

      5)客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序列号是seq=u+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2∗∗MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。

      6)服务器只要收到了客户端发出的确认,立即进入CLOSED状态。同样,撤销TCB后,就结束了这次的TCP连接。可以看到,服务器结束TCP连接的时间要比客户端早一些。

      总结:由TCP的三次握手和四次断开可以看出,TCP使用面向连接的通信方式, 大大提高了数据通信的可靠性,使发送数据端和接收端在数据正式传输前就有了交互, 为数据正式传输打下了可靠的基础。

      常见问题:

      1. 什么连接的时候是三次握手,关闭的时候却是四次握手?

        答:因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。

      2. 为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?

        答:虽然按道理,四个报文都发送完毕,我们可以直接进入CLOSE状态了,但是我们必须假象网络是不可靠的,有可以最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。在Client发送出最后的ACK回复,但该ACK可能丢失。Server如果没有收到ACK,将不断重复发送FIN片段。所以Client不能立即关闭,它必须确认Server接收到了该ACK。Client会在发送出ACK之后进入到TIME_WAIT状态。Client会设置一个计时器,等待2MSL的时间。如果在该时间内再次收到FIN,那么Client会重发ACK并再次等待2MSL。所谓的2MSL是两倍的MSL(Maximum Segment Lifetime)。MSL指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。如果直到2MSL,Client都没有再次收到FIN,那么Client推断ACK已经被成功接收,则结束TCP连接。

      3. 为什么不能用两次握手进行连接?

        3次握手完成两个重要的功能,既要双方做好发送数据的准备工作(双方都知道彼此已准备好),也要允许双方就初始序列号进行协商,这个序列号在握手过程中被发送和确认。现在把三次握手改成仅需要两次握手,死锁是可能发生的。作为例子,考虑计算机S和C之间的通信,假定C给S发送一个连接请求分组,S收到了这个分组,并发 送了确认应答分组。按照两次握手的协定,S认为连接已经成功地建立了,可以开始发送数据分组。可是,C在S的应答分组在传输中被丢失的情况下,将不知道S 是否已准备好,不知道S建立什么样的序列号,C甚至怀疑S是否收到自己的连接请求分组。在这种情况下,C认为连接还未建立成功,将忽略S发来的任何数据分 组,只等待连接确认应答分组。而S在发出的分组超时后,重复发送同样的分组。这样就形成了死锁。

      4. 如果已经建立了连接,但是客户端突然出现故障了怎么办?

        TCP还设有一个保活计时器,显然,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒钟发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。

    • TCP拥塞控制:由4个核心算法组成:“慢启动”(Slow Start)、“拥塞避免”(Congestion voidance)、“快速重传 ”(Fast Retransmit)、“快速恢复”(Fast Recovery)。

    • HTTP1.0和1.1以及HTTPS的特点和区别:

      1. 短连接和长连接
      2. 错误状态响应码
      3. 缓存处理
      4. 带宽优化及网络连接的使用
    • Cookie和Session:会话跟踪技术,Cookie通过在客户端记录信息确定用户身份,Session通过在服务端记录信息确定用户身份。由于HTTP是一种无状态的协议,服务器单从网络连接上无从知道客户身份。怎么办呢?就给客户端们颁发一个通行证吧,每人一个,无论谁访问都必须携带自己通行证。这样服务器就能从通行证上确认客户身份了。这就是Cookie的工作原理。如果说Cookie机制是通过检查客户身上的“通行证”来确定客户身份的话,那么Session机制就是通过检查服务器上的“客户明细表”来确认客户身份。Session相当于程序在服务器上建立的一份客户档案,客户来访的时候只需要查询客户档案表就可以了。Session的使用比Cookie方便,但是过多的Session存储在服务器内存中,会对服务器造成压力。两者区别如下:

      1. cookie数据存放在客户的浏览器上,session数据放在服务器上
      2. cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗考虑到安全应当使用session。
      3. 设置cookie时间可以使cookie过期。但是使用session-destory(),我们将会销毁会话。
      4. session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能考虑到减轻服务器性能方面,应当使用cookie。
      5. 单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。(Session对象没有对存储的数据量的限制,其中可以保存更为复杂的数据类型)
      6. 两者最大的区别在于生存周期,一个是IE启动到IE关闭.(浏览器页面一关 ,session就消失了),一个是预先设置的生存周期,或永久的保存于本地的文件。

      注意:

      ​ session很容易失效,用户体验很差;

      ​ 虽然cookie不安全,但是可以加密 ;

      ​ cookie也分为永久和暂时存在的;

      ​ 浏览器有禁止cookie功能 ,但一般用户都不会设置;

      ​ session一定要设置失效时间,要不然浏览器关闭就消失了;

      请求方法get和post的区别:

      1. 安全性:GET安全性非常低,POST安全性较高。因为GET请求的数据会暴露在地址栏中,而POST请求则不会。但是GET的执行效率比POST方法好。
      2. 数据量:GET传送的数据量较小,不能大于2KB。POST传送的数据量较大,一般默认为不受限制。
      3. 原理不同:一般我们在浏览器输入一个网址访问网站都是GET请求;在FORM表单中,可以通过设置Method指定提交方式为GET或者POST提交方式,默认为GET提交方式。HTTP定义了与服务器交互的不同方式,其中最基本的四种:GET,POST,PUT,DELETE,HEAD,其中GET和HEAD被称为安全方法,因为使用GET和HEAD的HTTP请求不会产生什么动作。不会产生动作意味着GET和HEAD的HTTP请求不会在服务器上产生任何结果。但是安全方法并不是什么动作都不产生,这里的安全方法仅仅指不会修改信息。根据HTTP规范,POST可能会修改服务器上的资源的请求。
  • DNS(域名)协议的功能:将主机域名转化为IP地址,使得用户能够方便的访问各种Internet资源与服务,DNS是Internet各种应用层协议实现的基础。TCP/IP中使用IP地址和端口号来确定网络上某一台主机上的某一个程序,但是IP地址是点分十进制,不方便记忆。因此,就出现了域名,如:www.baidu.com。

  • 浏览器输入URL到打开页面的过程:

    1. 进行网络通信:在浏览器中输入url->应用层DNS解析域名->应用层客户端发送HTTP请求->传输层TCP传输报文->网络层IP协议查询MAC地址->数据到达数据链路层->服务器接收数据->服务器响应请求->服务器返回相应文件。

      互联网内各网络设备间的通信都遵循TCP/IP协议,利用TCP/IP协议族进行网络通信时,会通过分层顺序与对方进行通信。分层由高到低分别为:应用层、传输层、网络层、数据链路层。发送端从应用层往下走,接收端从数据链路层网上走。如图所示:

      1. 页面渲染:jiexiHTML以构建DOM树 –> 构建渲染树–> 布局渲染树 –> 绘制渲染树。

IP

IP地址(Internet Protocol Address)是指互联网协议地址,又译为网际协议地址。

IP地址是IP协议提供的一种统一的地址格式,它为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物理地址的差异。

  • IP地址的分类
    • ipv4/ipv6
      • IPV4 127.0.0.1,4个字节组成
      • IPV6 fe80::85b:86a2:2867:b900%7,128位,8个无符号整数。
    • 公网(互联网)、私网(局域网)
      • ABCD类地址
      • 192.168.xx.xx 一般来说都是局域网,专门给组织内部使用
  • Java中的InetAddress类

端口

端口表示计算机上的一个程序的进程;

  • 不同的进程有不同的端口号,用来区分软件

  • 被规定的范围:0~65535

  • 单个协议下端口号不能冲突

  • 端口分类

    • 公有端口0~1023,部分协议默认端口号如下:

      • HTTP:80
      • HTTPS:443
      • FTP:21
      • Telent:23
    • 程序注册端口号范围:1024~49151,用来分给用户或者程序

      • Tomcat端口号默认为:8080
      • MySQL端口号默认为:3306
      • Oracle端口号默认为:1521
    • 动态、私有端口号范围:43152~65535

      netstat -ano #查看所有的端口
      netstat -ano|findstr "5900" #查看指定的端口
      tasklist|findstr "18012" #查看指定端口的进程
      Ctrl + shift + Esc #快捷打开任务管理器
      

      实例1:通过静态类InetAddress中的方法来获取IP地址等信息

      package com.lurenj.lesson01;
      
      import java.net.InetAddress;
      import java.net.UnknownHostException;
      
      //测试IP
      public class TestInetAdress {
          public static void main(String[] args) throws UnknownHostException {
              try {
      
                  //查询本机地址
                      //方法一
                  InetAddress inetAddress1 = InetAddress.getByName("127.0.0.1");
                  System.out.println(inetAddress1);
                      //方法二
                  InetAddress inetAddress3 = InetAddress.getByName("localhost");
                  System.out.println(inetAddress3);
                      //方法三
                  InetAddress inetAddress4 = InetAddress.getLocalHost();
                  System.out.println(inetAddress4);
                 //查询网站IP地址
                  InetAddress inetAddress2 = InetAddress.getByName("www.baidu.com");
                  System.out.println(inetAddress2);
                  //常用方法
                  System.out.println(inetAddress2.getAddress());//一般情况不用,会返回一组地址
                  System.out.println(inetAddress2.getCanonicalHostName());//规范的名字
                  System.out.println(inetAddress2.getHostAddress());//规范的名字
                  System.out.println(inetAddress2.getHostName());//域名或者自己电脑的名字
      
              } catch (UnknownHostException e) {
                  e.printStackTrace();
              }
          }
      }
      

      实例2:通过InetSocketAddress类中的方法来获取地址、端口号等信息

      package com.lurenj.lesson01;
      
      import java.net.InetSocketAddress;
      
      public class TestInetSocketAddress {
          public static void main(String[] args) {
              InetSocketAddress socketAddress = new InetSocketAddress("127.0.0.1", 8080);
              InetSocketAddress socketAddress2 = new InetSocketAddress("localhost", 8080);
              System.out.println(socketAddress);
              System.out.println(socketAddress2);
      
              System.out.println(socketAddress.getAddress());
              System.out.println(socketAddress.getHostName());//地址
              System.out.println(socketAddress.getPort());//端口
          }
      }
      
posted @   lurenj  阅读(159)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示