第一场:
第二场: 心里憋了一万个草泥马来到的第二家
心里在想,还来?
):没什么好说的,就是为了保持一次网络通信交互正常接着进入正题
网络编程的本质是多台计算机之间的数据交换。数据传递本身没有多大的难度,不就是把一个设备中的数据发送给其他设备,然后接受另外一个设备反馈的数据。现在的网络编程基本上都是基于请求/响应方式的,也就是一个设备发送请求数据给另外一个,然后接收另一个设备的反馈。在网络编程中,发起连接程序,也就是发送第一次请求的程序,被称作客户端(Client),等待其他程序连接的程序被称作服务器(Server)。客户端程序可以在需要的时候启动,而服务器为了能够时刻相应连接,则需要一直启动。
例如以打电话为例,首先拨号的人类似于客户端,接听电话的人必须保持电话畅通类似于服务器。连接一旦建立以后,就客户端和服务器端就可以进行数据传递了,而且两者的身份是等价的。在一些程序中,程序既有客户端功能也有服务器端功能,最常见的软件就是QQ、微信这类软件了。
在TCP/IP协议中IP层主要负责网络主机的定位,数据传输的路由,由IP地址可以唯一地确定Internet上的一台主机。
而TCP层则提供面向应用的可靠(TCP)的或非可靠(UDP)的数据传输机制,这是网络编程的主要对象,一般不需要关心IP层是如何处理数据的。
目前较为流行的网络编程模型是客户机/服务器(C/S)结构。即通信双方一方作为服务器等待客户提出请求并予以响应。客户则在需要服务时向服务器提 出申请。服务器一般作为守护进程始终运行,监听网络端口,一旦有客户请求,就会启动一个服务进程来响应该客户,同时自己继续监听服务端口,使后来的客户也 能及时得到服务。
TCP/IP参考模型
TCP/IP四层协议(数据链路层、网络层、传输层、应用层)
硬件
和软件加到物理线路,这样就构成了数据链路,1.1 什么是TCP/IP和UDP
TCP/IP即传输控制/网络协议,是面向连接的协议,发送数据前要先建立连接(发送方和接收方的成对的两个之间必须建 立连接),TCP提供可靠的服务,也就是说,通过TCP连接传输的数据不会丢失,没有重复,并且按顺序到达
UDP它是属于TCP/IP协议族中的一种。是无连接的协议,发送数据前不需要建立连接,是没有可靠性的协议。因为不需要建立连接所以可以在在网络上以任何可能的路径传输,因此能否到达目的地,到达目的地的时间以及内容的正确性都是不能被保证的。
1.2 TCP与UDP区别:
TCP是面向连接的协议,发送数据前要先建立连接,TCP提供可靠的服务,也就是说,通过TCP连接传输的数据不会丢失,没有重复,并且按顺序到达;
UDP是无连接的协议,发送数据前不需要建立连接,是没有可靠性;
TCP通信类似于于要打个电话,接通了,确认身份后,才开始进行通行;
UDP通信类似于学校广播,靠着广播播报直接进行通信。
TCP只支持点对点通信,UDP支持一对一、一对多、多对一、多对多;
TCP是面向字节流的,UDP是面向报文的; 面向字节流是指发送数据时以字节为单位,一个数据包可以拆分成若干组进行发送,而UDP一个报文只能一次发完。
TCP首部开销(20字节)比UDP首部开销(8字节)要大
UDP 的主机不需要维持复杂的连接状态表
1.3 TCP和UDP的应用场景:
1.4 形容一下TCP和UDP
TCP通信可看作打电话:
李三(拨了个号码):喂,是王五吗? 王五:哎,您谁啊? 李三:我是李三,我想给你说点事儿,你现在方便吗? 王五:哦,我现在方便,你说吧。 甲:那我说了啊? 乙:你说吧。 (连接建立了,接下来就是说正事了…)
UDP通信可看为学校里的广播:
播音室:喂喂喂!全体操场集合
1.5 运行在TCP 或UDP的应用层协议分析。
运行在TCP协议上的协议:
运行在UDP协议上的协议:
运行在TCP和UDP协议上:
什么是ARP协议 (Address Resolution Protocol)?
ARP协议完成了IP地址与物理地址的映射。每一个主机都设有一个 ARP 高速缓存,里面有所在的局域网上的各主机和路由器的 IP 地址到硬件地址的映射表。当源主机要发送数据包到目的主机时,会先检查自己的ARP高速缓存中有没有目的主机的MAC地址,如果有,就直接将数据包发到这个MAC地址,如果没有,就向所在的局域网发起一个ARP请求的广播包(在发送自己的 ARP 请求时,同时会带上自己的 IP 地址到硬件地址的映射),收到请求的主机检查自己的IP地址和目的主机的IP地址是否一致,如果一致,则先保存源主机的映射到自己的ARP缓存,然后给源主机发送一个ARP响应数据包。源主机收到响应数据包之后,先添加目的主机的IP地址与MAC地址的映射,再进行数据传送。如果源主机一直没有收到响应,表示ARP查询失败。
如果所要找的主机和源主机不在同一个局域网上,那么就要通过 ARP 找到一个位于本局域网上的某个路由器的硬件地址,然后把分组发送给这个路由器,让这个路由器把分组转发给下一个网络。剩下的工作就由下一个网络来做。
什么是NAT (Network Address Translation, 网络地址转换)?
从输入址到获得页面的过程?
1.6 TCP的三次握手
1.6.1 什么是TCP的三次握手
1.6.2 三次握手的具体细节
1.6.3 用现实理解三次握手的具体细节
1.6.4 建立连接可以两次握手吗?为什么?
1.6.5 可以采用四次握手吗?为什么?
1.6.6 第三次握手中,如果客户端的ACK未送达服务器,会怎样?
1.6.7 如果已经建立了连接,但客户端出现了故障怎么办?
1.6.8 初始序列号是什么?
1.7 TCP的四次挥手
1.7.1 什么是TCP的四次挥手
1.7.2 四次挥手的具体细节
1.7.3 用现实理解三次握手的具体细节TCP的四次挥手
1.7.4 为什么不能把服务器发送的ACK和FIN合并起来,变成三次挥手(CLOSE_WAIT状态意义是什么)?
1.7.5 如果第二次挥手时服务器的ACK没有送达客户端,会怎样?
1.7.6 客户端TIME_WAIT状态的意义是什么?
1 什么是Socket
网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个Socket。Socket通常用来实现客户方和服务方的连接。Socket是TCP/IP协议的一个十分流行的编程界面,一个Socket由一个IP地址和一个端口号唯一确定。
但是,Socket所支持的协议种类也不光TCP/IP、UDP,因此两者之间是没有必然联系的。在Java环境下,Socket编程主要是指基于TCP/IP协议的网络编程。
socket连接就是所谓的长连接,客户端和服务器需要互相连接,理论上客户端和服务器端一旦建立起连接将不会主动断掉的,但是有时候网络波动还是有可能的
Socket偏向于底层。一般很少直接使用Socket来编程,框架底层使用Socket比较多,
2 socket属于网络的那个层面
3 Socket通讯的过程
基于TCP:服务器端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端连接。在这时如果有个客户端初始化一个Socket,然后连接服务器(connect),如果连接成功,这时客户端与服务器端的连接就建立了。客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束。
基于UDP:UDP 协议是用户数据报协议的简称,也用于网络数据的传输。虽然 UDP 协议是一种不太可靠的协议,但有时在需要较快地接收数据并且可以忍受较小错误的情况下,UDP 就会表现出更大的优势。我客户端只需要发送,服务端能不能接收的到我不管
4 TCP协议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();
}
}
}
先运行服务端,在运行客户端
。测试结果发送成功:
·
5 UDP协议Socket代码示例:
先运行服务端,在运行客户端
//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();
}
}
}
先运行服务端,在运行客户端
。测试结果成功发送成功:
6 Socket的常用类
类名 | 用于 | 作用 |
---|---|---|
Socket | TCP协议 | Socket类同时工作于客户端和服务端,所有方法都是通用的,这个类三个主要作用,校验包信息,发起连接(Client),操作流数据(Client/Server) |
ServerSocket | TCP协议 | ServerSocket表示为服务端,主要作用就是绑定并监听一个服务器端口,为每个建立连接的客户端“克隆/映射”一个Socket对象,具体数据操作都是通过这个Socket对象完成的,ServerSocket只关注如何和客户端建立连接 |
DatagramSocket | ODP协议 | DatagramSocket 类用于表示发送和接收数据报包的套接字。 |
DatagramPacket | ODP协议 | DatagramPacket 类用来表示数据报包,数据报包用来实现无连接包投递服务。 |
InetAddress | IP+端口号 | Java提供了InetAddress类来代表互联网协议(IP)地址,InetAddress类没有提供构造器,而是提供了如下两个静态方法来获取InetAddress实例: |
InetSocketAddress | IP+端口号 | 在使用Socket来连接服务器时最简单的方式就是直接使用IP和端口,但Socket类中并未提供这种方式,而是靠SocketAddress的子类InetSocketAddress来实现 IP 地址 + 端口号的创建,不依赖任何协议。 |
什么是Http协议?
Socket和http的区别和应用场景
Socket连接就是所谓的长连接,理论上客户端和服务器端一旦建立起连接将不会主动断掉;
Socket适用场景:网络游戏,银行持续交互,直播,在线视屏等。
http连接就是所谓的短连接,即客户端向服务器端发送一次请求,服务器端响应后连接即会断开等待下次连接
http适用场景:公司OA服务,互联网服务,电商,办公,网站等等等等
什么是http的请求体?
http的响应报文有哪些?
http和https的区别?
其实HTTPS就是从HTTP加上加密处理(一般是SSL安全通信线路)+认证+完整性保护
区别:
HTTPS工作原理
一次完整的HTTP请求所经历几个步骤?
HTTP通信机制是在一次完整的HTTP通信过程中,Web浏览器与Web服务器之间将完成下列7个步骤:
建立TCP连接
怎么建立连接的,看上面的三次捂手
Web浏览器向Web服务器发送请求行
一旦建立了TCP连接,Web浏览器就会向Web服务器发送请求命令。例如:GET /sample/hello.jsp HTTP/1.1。
Web浏览器发送请求头
浏览器发送其请求命令之后,还要以头信息的形式向Web服务器发送一些别的信息,之后浏览器发送了一空白行来通知服务器,它已经结束了该头信息的发送。
Web服务器应答
客户机向服务器发出请求后,服务器会客户机回送应答, HTTP/1.1 200 OK ,应答的第一部分是协议的版本号和应答状态码。
Web服务器发送应答头
正如客户端会随同请求发送关于自身的信息一样,服务器也会随同应答向用户发送关于它自己的数据及被请求的文档。
Web服务器向浏览器发送数据
Web服务器向浏览器发送头信息后,它会发送一个空白行来表示头信息的发送到此为结束,接着,它就以Content-Type应答头信息所描述的格式发送用户所请求的实际数据。
Web服务器关闭TCP连接
常用HTTP状态码是怎么分类的,有哪些常见的状态码?
HTTP状态码表示客户端HTTP请求的返回结果、标识服务器处理是否正常、表明请求出现的错误等。
状态码的类别:
类别 描述 1xx: 指示信息–表示请求已接收,正在处理 2xx: 成功–表示请求已被成功接收、理解、接受 3xx: 重定向–要完成请求必须进行更进一步的操作 4xx: 客户端错误–请求有语法错误或请求无法实现 5xx: 服务器端错误–服务器未能实现合法的请求
状态码 描述 200: 请求被正常处理 204: 请求被受理但没有资源可以返回 206: 客户端只是请求资源的一部分,服务器只对请求的部分资源执行GET方法,相应报文中通过Content-Range指定范围的资源。 301: 永久性重定向 302: 临时重定向 303: 与302状态码有相似功能,只是它希望客户端在请求一个URI的时候,能通过GET方法重定向到另一个URI上 304: 发送附带条件的请求时,条件不满足时返回,与重定向无关 307: 临时重定向,与302类似,只是强制要求使用POST方法 400: 请求报文语法有误,服务器无法识别 401: 请求需要认证 403: 请求的对应资源禁止被访问 404: 服务器无法找到对应资源 500: 服务器内部错误 503: 服务器正忙
Http协议中有那些请求方式
请求方式 描述 GET: 用于请求访问已经被URI(统一资源标识符)识别的资源,可以通过URL传参给服务器 POST: 用于传输信息给服务器,主要功能与GET方法类似,但一般推荐使用POST方式。 PUT: 传输文件,报文主体中包含文件内容,保存到对应URI位置。 HEAD: 获得报文首部,与GET方法类似,只是不返回报文主体,一般用于验证URI是否有 > 效。 PATCH: 客户端向服务器传送的数据取代指定的文档的内容(部分取代) TRACE: 回显客户端请求服务器的原始请求报文,用于"回环"诊断 DELETE: 删除文件,与PUT方法相反,删除对应URI位置的文件。 OPTIONS: 查询相应URI支持的HTTP方法。
GET方法与POST方法的区别
区别一: get重点在从服务器上获取资源,post重点在向服务器发送数据;
区别二: Get传输的数据量小,因为受URL长度限制,但效率较高; Post可以传输大量数据,所以上传文件时只能用Post方式;
区别三: get是不安全的,因为get请求发送数据是在URL上,是可见的,可能会泄露私密信息,如密码等; post是放在请求头部的,是安全的
http版本的对比
HTTP1.0版本的特性:
HTTP1.1版本新特性
HTTP2.0版本的特性
什么是对称加密与非对称加密
对称密钥加密是指加密和解密使用同一个密钥的方式,这种方式存在的最大问题就是密钥发送问题,即如何安全地将密钥发给对方;
而非对称加密是指使用一对非对称密钥,即公钥和私钥,公钥可以随意发布,但私钥只有自己知道。发送密文的一方使用对方的公钥进行加密处理,对方接收到加密信息后,使用自己的私钥进行解密。 由于非对称加密的方式不需要发送用来解密的私钥,所以可以保证安全性;但是和对称加密比起来,非常的慢
cookie和session对于HTTP有什么用?
什么是cookie
什么是session
session 是浏览器和服务器会话过程中,服务器会分配的一块储存空间给session。
服务器默认为客户浏览器的cookie中设置 sessionid,这个sessionid就和cookie对应,浏览器在向服务器请求过程中传输的cookie 包含 sessionid ,服务器根据传输cookie 中的 sessionid 获取出会话中存储的信息,然后确定会话的身份信息。
cookie与session区别
cookie和session对于HTTP有什么用?
什么是cookie
什么是session
session 是浏览器和服务器会话过程中,服务器会分配的一块储存空间给session。
服务器默认为客户浏览器的cookie中设置 sessionid,这个sessionid就和cookie对应,浏览器在向服务器请求过程中传输的cookie 包含 sessionid ,服务器根据传输cookie 中的 sessionid 获取出会话中存储的信息,然后确定会话的身份信息。
cookie与session区别
更多的java课程学习路线,笔记,面试等架构资料,需要的同学可以私信我(面试)即可免费获取!