网络编程小结
网络模型

TCP/IP四层协议(数据链路层、网络层、传输层、应用层)
-
应用层 应用层最靠近用户的一层,是为计算机用户提供应用接口,也为用户直接提供各种网 络服务。我们常见应用层的网络服务协议有:HTTP,HTTPS,FTP,TELNET等。
-
传输层 建立了主机端到端的链接,传输层的作用是为上层协议提供端到端的可靠和透明的数 据传输服务,包括处理差错控制和流量控制等问题。该层向高层屏蔽了下层数据通信的细 节,使高层用户看到的只是在两个传输实体间的一条主机到主机的、可由用户控制和设定 的、可靠的数据通路。我们通常说的,TCP UDP就是在这一层。端口号既是这里的“端”。
-
网络层 本层通过IP寻址来建立两个节点之间的连接,为源端的运输层送来的分组,选择合适 的路由和交换节点,正确无误地按照地址传送给目的端的运输层。就是通常说的IP层。这一 层就是我们经常说的IP协议层。IP协议是Internet的基础。
-
数据链路层 通过一些规程或协议来控制这些数据的传输,以保证被传输数据的正确性。实现 这些规程或协议的 硬件 和软件加到物理线路,这样就构成了数据链路,
-
TCP与UDP区别
TCP打电话;UDP发短信、广播。
TCP是面向连接的协议,发送数据前要先建立连接,TCP提供可靠的服务,也就是说,通过TCP连 接传输的数据不会丢失,没有重复,并且按顺序到达;UDP是无连接的协议,发送数据前不需要建立连接,是没有可靠性;
TCP通信类似于于要打个电话,接通了,确认身份后,才开始进行通行;UDP通信类似于学校广播,靠着广播播报直接进行通信。
TCP只支持点对点通信,UDP支持一对一、一对多、多对一、多对多;
TCP是面向字节流的,UDP是面向报文的; 面向字节流是指发送数据时以字节为单位,一个数据 包可以拆分成若干组进行发送,而UDP一个报文只能一次发完。
TCP首部开销(20字节)比UDP首部开销(8字节)要大 UDP 的主机不需要维持复杂的连接状态表
TCP和UDP的应用场景
对某些实时性要求比较高的情况使用UDP,比如游戏,媒体通信,实时直播,即使出现传输错误 也可以容忍;
其它大部分情况下,HTTP都是用TCP,因为要求传输的内容可靠,不出现丢失的情况
ARP协议:ARP协议完成了IP地址与物理地址的映射。
NAT (Network Address Translation, 网络地址转换:
从输入址到获得页面的过程:
-
浏览器查询 DNS,获取域名对应的IP地址:具体过程包括浏览器搜索自身的DNS缓存、搜索操作系 统的DNS缓存、读取本地的Host文件和向本地DNS服务器进行查询等。对于向本地DNS服务器进 行查询,如果要查询的域名包含在本地配置区域资源中,则返回解析结果给客户机,完成域名解析 (此解析具有权威性);如果要查询的域名不由本地DNS服务器区域解析,但该服务器已缓存了此网 址映射关系,则调用这个IP地址映射,完成域名解析(此解析不具有权威性)。如果本地域名服务 器并未缓存该网址映射关系,那么将根据其设置发起递归查询或者迭代查询;
-
浏览器获得域名对应的IP地址以后,浏览器向服务器请求建立链接,发起三次握手;
-
TCP/IP链接建立起来后,浏览器向服务器发送HTTP请求;
-
服务器接收到这个请求,并根据路径参数映射到特定的请求处理器进行处理,并将处理结果及相应 的视图返回给浏览器;
-
浏览器解析并渲染视图,若遇到对js文件、css文件及图片等静态资源的引用,则重复上述步骤并 向服务器请求这些资源;
-
浏览器根据其请求到的资源、数据渲染页面,最终向用户呈现一个完整的页面。
三次握手:
-
客户端向服务端发送SYN
-
服务端返回SYN,ACK
-
客户端发送ACK
两次握手的问题:
因为可能会出现已失效的连接请求报文段又传到了服务器端。 > client 发出的第一个连接请求报文 段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达 server。本来这是一个早已失效的报文段。但 server 收到此失效的连接请求报文段后,就误认为 是 client 再次发出的一个新的连接请求。于是就向 client 发出确认报文段,同意建立连接。假设 不采用 “三次握手”,那么只要 server 发出确认,新的连接就建立了。由于现在 client 并没有发出 建立连接的请求,因此不会理睬 server 的确认,也不会向 server 发送数据。但 server 却以为新 的运输连接已经建立,并一直等待 client 发来数据。这样,server 的很多资源就白白浪费掉了。 采用 “三次握手” 的办法可以防止上述现象发生。例如刚才那种情况,client 不会向 server 的确认 发出确认。server 由于收不到确认,就知道 client 并没有要求建立连接。 而且,两次握手无法保证Client正确接收第二次握手的报文(Server无法确认Client是否收到), 也无法保证Client和Server之间成功互换初始序列号。
第三次握手中,如果客户端的ACK未送达服务器,会怎样:
Server端:由于Server没有收到ACK确认,因此会每隔 3秒 重发之前的SYN+ACK(默认重发五 次,之后自动关闭连接进入CLOSED状态),Client收到后会重新传ACK给Server。
Client端,会出现两种情况:
-
在Server进行超时重发的过程中,如果Client向服务器发送数据,数据头部的ACK是为1的, 所以服务器收到数据之后会读取 ACK number,进入 establish 状态
-
在Server进入CLOSED状态之后,如果Client向服务器发送数据,服务器会以RST包应答。
-
如果已经建立了连接,但客户端出现了故障怎么办:
服务器每收到一次客户端的请求后都会重新复位一个计时器,时间通常是设置为2小时,若两小时 还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒钟发送一次。若 一连发送10个探测报文仍然没反应,服务器就认为客户端出了故 障,接着就关闭连接。
初始系列号
TCP连接的一方A,随机选择一个32位的序列号(Sequence Number)作为发送数据的初始序列 号(Initial Sequence Number,ISN),比如为1000,以该序列号为原点,对要传送的数据进行 编号:1001、1002...三次握手时,把这个初始序列号传送给另一方B,以便在传输数据时,B可以 确认什么样的数据编号是合法的;同时在进行数据传输时,A还可以确认B收到的每一个字节,如 果A收到了B的确认编号(acknowledge number)是2001,就说明编号为1001-2000的数据已经 被B成功接受
四次挥手
四次挥手断开连接是因为要确定数据全部传书完了
-
客户与服务器交谈结束之后,客户要结束此次会话,就会对服务器说:我要关闭连接了(第一 次 挥手)
-
服务器收到客户的消息后说:好的,你要关闭连接了。(第二次挥手)
-
然后服务器确定了没有话要和客户说了,服务器就会对客户说,我要关闭连接了。(第三次挥 手)
-
客户收到服务器要结束连接的消息后说:已收到你要关闭连接的消息。(第四次挥手),才关闭
如果第二次挥手时服务器的ACK没有送达客户端,会怎样?
客户端没有收到ACK确认,会重新发送FIN请求。
客户端TIME_WAIT状态的意义是什么?
第四次挥手时,客户端发送给服务器的ACK有可能丢失,TIME_WAIT状态就是用来重发可能丢失的 ACK报文。如果Server没有收到ACK,就会重发FIN,如果Client在2*MSL的时间内收到了FIN,就 会重新发送ACK并再次等待2MSL,防止Server没有收到ACK而不断重发FIN。 MSL(Maximum Segment Lifetime),指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的 最大时间。如果直到2MSL,Client都没有再次收到FIN,那么Client推断ACK已经被成功接收,则 结束TCP连接。
Socket
Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket 其实就是一个外观模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简 单的接口就是全部,让Socket去组织数据,以符合指定的协议。
服务端
package com.test.io;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
//TCP协议Socket使用BIO进行通行:服务端
public class BIOServer {
// 在main线程中执行下面这些代码
public static void main(String[] args) {
//1单线程服务
ServerSocket server = null;
Socket socket = null;
InputStream in = null;
OutputStream out = null;
try {
server = new ServerSocket(8000);
System.out.println("服务端启动成功,监听端口为8000,等待客户端连接...");
while (true){
socket = server.accept(); //等待客户端连接
System.out.println("客户连接成功,客户信息为:" +
socket.getRemoteSocketAddress());
in = socket.getInputStream();
byte[] buffer = new byte[1024];
int len = 0;
//读取客户端的数据
while ((len = in.read(buffer)) > 0) {
System.out.println(new String(buffer, 0, len));
}
//向客户端写数据
out = socket.getOutputStream();
out.write("hello!".getBytes());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
客户端
package com.test.io;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;
//TCP协议Socket:客户端
public class Client01 {
public static void main(String[] args) throws IOException {
//创建套接字对象socket并封装ip与port
Socket socket = new Socket("127.0.0.1", 8000);
//根据创建的socket对象获得一个输出流
OutputStream outputStream = socket.getOutputStream();
//控制台输入以IO的形式发送到服务器
System.out.println("TCP连接成功 \n请输入:");
while(true){
byte[] car = new Scanner(System.in).nextLine().getBytes();
outputStream.write(car);
System.out.println("TCP协议的Socket发送成功");
//刷新缓冲区
outputStream.flush();
}
}
}
//UDP协议Socket:服务端
public class Server1 {
public static void main(String[] args) {
try {
//DatagramSocket代表声明一个UDP协议的Socket
DatagramSocket socket = new DatagramSocket(8888);
//byte数组用于数据存储。
byte[] car = new byte[1024];
//DatagramPacket 类用来表示数据报包DatagramPacket
DatagramPacket packet = new DatagramPacket(car, car.length);
// //创建DatagramPacket的receive()方法来进行数据的接收,等待接收一个socket请
求后才执行后续操作;
System.out.println("等待UDP协议传输数据");
socket.receive(packet);
//packet.getLength返回将要发送或者接收的数据的长度。
int length = packet.getLength();
System.out.println("啥东西来了:" + new String(car, 0, length));
socket.close();
System.out.println("UDP协议Socket接受成功");
} catch (IOException e) {
e.printStackTrace();
}
}
}
客户端
//UDP协议Socket:客户端
public class Client1 {
public static void main(String[] args) {
try {
//DatagramSocket代表声明一个UDP协议的Socket
DatagramSocket socket = new DatagramSocket(2468);
//字符串存储人Byte数组
byte[] car = "UDP协议的Socket请求,有可能失败哟".getBytes();
//InetSocketAddress类主要作用是封装端口
InetSocketAddress address = new InetSocketAddress("127.0.0.1", 8888);
//DatagramPacket 类用来表示数据报包DatagramPacket
DatagramPacket packet = new DatagramPacket(car, car.length,
address);
//send() 方法发送数据包。
socket.send(packet);
System.out.println("UDP协议的Socket发送成功");
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Socket和http的区别和应用场景
Socket连接就是所谓的长连接,理论上客户端和服务器端一旦建立起连接将不会主动断掉; Socket适用场景:网络游戏,银行持续交互,直播,在线视屏等。
http连接就是所谓的短连接,即客户端向服务器端发送一次请求,服务器端响应后连接即会断开等 待下次连接 http适用场景:公司OA服务,互联网服务,电商,办公,网站等等等等
HTTP请求体由:请求行 、请求头、请求数据组成的,get请求没有请求体。
响应报文包含三部分:状态行、响应首部字段、响应内容实体
http和https的区别? 其实HTTPS就是从HTTP加上加密处理(一般是SSL安全通信线路)+认证+完整性保护 区别:
-
http需要拿到ca证书,需要钱的
-
端口不一样,http是80,https443
-
http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。
-
http和https使用的是完全不同的连接方式(http的连接很简单,是无状态的;HTTPS 协议是 由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。) HTTPS工作原理 一、首先HTTP请求服务端生成证书,客户端对证书的有效期、合法性、域名是否与请求的域名一 致、证书的公钥(RSA加密)等进行校验; 二、客户端如果校验通过后,就根据证书的公钥的有效, 生成随机数,随机数使用公钥进行加密 (RSA加密); 三、消息体产生的后,对它的摘要进行MD5(或者SHA1)算法加密,此时就得到了RSA签名; 四、发送给服务端,此时只有服务端(RSA私钥)能解密。 五、解密得到的随机数,再用AES加密,作为密钥(此时的密钥只有客户端和服务端知道)。
一次完整的HTTP请求所经历几个步骤
-
建立TCP连接 怎么建立连接的,看上面的三次捂手
-
Web浏览器向Web服务器发送请求行 一旦建立了TCP连接,Web浏览器就会向Web服务器发送请求命令。例如:GET /sample/hello.jsp HTTP/1.1。
-
Web浏览器发送请求头 浏览器发送其请求命令之后,还要以头信息的形式向Web服务器发送一些别的信息,之后浏览器发送 了一空白行来通知服务器,它已经结束了该头信息的发送。
-
Web服务器应答 客户机向服务器发出请求后,服务器会客户机回送应答, HTTP/1.1 200 OK ,应答的第一部分是协议 的版本号和应答状态码。
-
Web服务器发送应答头 类别 描述 1xx: 指示信息–表示请求已接收,正在处理 2xx: 成功–表示请求已被成功接收、理解、接受 3xx: 重定向–要完成请求必须进行更进一步的操作 4xx: 客户端错误–请求有语法错误或请求无法实现 5xx: 服务器端错误–服务器未能实现合法的请求 正如客户端会随同请求发送关于自身的信息一样,服务器也会随同应答向用户发送关于它自己的数据及 被请求的文档。
-
Web服务器向浏览器发送数据 Web服务器向浏览器发送头信息后,它会发送一个空白行来表示头信息的发送到此为结束,接着,它 就以Content-Type应答头信息所描述的格式发送用户所请求的实际数据。
-
Web服务器关闭TCP连接
哪些常见的状态码:
类别描述
1xx: 指示信息–表示请求已接收,正在处理
2xx: 成功–表示请求已被成功接收、理解、接受
3xx: 重定向–要完成请求必须进行更进一步的操作
4xx: 客户端错误–请求有语法错误或请求无法实现
5xx: 服务器端错误–服务器未能实现合法的请求


GET方法与POST方法的区别
区别一: get重点在从服务器上获取资源,post重点在向服务器发送数据;
区别二: Get传输的数据量小,因为受URL长度限制,但效率较高; Post可以传输大量数据,所 以上传文件时只能用Post方式;
区别三: get是不安全的,因为get请求发送数据是在URL上,是可见的,可能会泄露私密信息, 如密码等; post是放在请求头部的,是安全的
cookie与session区别
-
cookie数据存放在客户端上,安全性较差,session数据放在服务器上,安全性相对更高
-
单个cookie保存的数据不能超过4K,session无此限制 信息后,使用自己的私钥进行解密。 由于 非对称加密的方式不需要发送用来解密的私钥,所以可以保证安全性;但是和对称加密比起来,非 常的慢
cookie和session对于HTTP有什么用?
HTTP协议本身是无法判断用户身份。所以需要cookie或者session

浙公网安备 33010602011771号