一、TCP的滑动窗口-确认重传
RTT:发送一个数据包到收到对应的ACK,所花费的时间
RTO:重传时间间隔
TCP使用滑动窗口做流量控制与乱序重排
- 保证TCP的可靠性
- 保证TCP的流控特性
二、HTTP
超文本传输协议
- 支持客户/服务器模式
- 简单快速
- 灵活
- 无连接 【1.1 使用长连接】
- 无状态
在浏览器地址栏键入URL,按下回车之后经历的流程
- DNS解析
- TCP连接
- 发送HTTP请求
- 服务器处理请求并返回HTTP报文
- 浏览器解析渲染页面
- 连接结束
HTTP状态码
GET POST
区别 | GET | POST |
---|---|---|
http报文层面 | 请求信息放在url | 放在报文中 |
数据层 | 符合幂等性和安全性 | 不符合 |
其他 | 可以被缓存、被存储 | 不行 |
cookie session
cookie
1、服务器发送给客户端的特殊信息,以文本的形式存放在客户端
2、客户端再次请求,会把cookie回发
3、服务器收到cookie,解析生成与客户端相应的内容
session
1、服务器端机制,在服务器上保存的信息
2、解析客户端请求并操作session id,按需保存状态信息
区别 | cookie | session |
---|---|---|
数据存放 | 浏览器上 | 服务器上 |
安全性 | 低 | 高 |
减轻服务器开销 | 使用 | 不使用 |
http https
SSL
加密
区别 | https | http |
---|---|---|
证书 | CA申请证书 | 不需要 |
传输 | 密文 | 明文 |
连接方式 | 443 | 80 |
安全性 | http + 加密 + 认证 + 完整性保护 | 不安全 |
socket
ip + 协议 + port 标记一个唯一的进程
使用TCP进行socket传输
client
package com.javabasic.socket;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class TCPClient {
public static void main(String[] args) throws IOException {
Socket socket = new Socket("127.0.0.1", 65000);
OutputStream os = socket.getOutputStream();
InputStream is = socket.getInputStream();
os.write(new String("hello world").getBytes());
int ch = 0;
byte[] buff = new byte[1024];
ch = is.read(buff);
String content = new String(buff, 0 , ch);
System.out.println(content);
is.close();
os.close();
socket.close();
}
}
server
package com.javabasic.socket;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class TCPServer {
public static void main(String[] args) throws IOException {
// 创建socket 并将socket绑定到65000端口
ServerSocket serverSocket = new ServerSocket(65000);
while (true) {
// 监听65000端口 知道客户端返回连接信息后才返回
Socket socket = serverSocket.accept();
// 获取客户端的请求信息后,执行相关的业务逻辑
new LengthCalculator(socket).start();
}
}
}
公用类
package com.javabasic.socket;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class LengthCalculator extends Thread {
private Socket socket;
public LengthCalculator(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try {
// 获取socket的输出流
OutputStream os = socket.getOutputStream();
// 获取socket的输入流
InputStream is = socket.getInputStream();
// 获取读取数组的长度
int ch = 0;
// 用来读取输入的内容,存储byte数组
byte[] buff = new byte[1024];
ch = is.read(buff);
// 将buff转换成字符串
String content = new String(buff, 0, ch);
System.out.println(content);
// 往输出流写入获取字符串的长度 并转换为byte数组
os.write(String.valueOf(content.length()).getBytes());
is.close();
os.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
UDP进行socket传输
server
package com.javabasic.socket;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class UDPServer {
public static void main(String[] args) throws IOException {
// 服务端接受客户端发送的数据报
DatagramSocket datagramSocket = new DatagramSocket(65001); // 监听端口号
byte[] buff = new byte[100]; // 存储从客户端接收到的内容
DatagramPacket packet = new DatagramPacket(buff, buff.length);
// 接受客户端发送过来的内容 并将内容封装进 DatagramPacket
datagramSocket.receive(packet);
byte[] data = packet.getData();
String content = new String(data, 0, packet.getLength());
System.out.println(content);
// 将要发送的内容转换为二进制
byte[] sendedContent = String.valueOf(content.length()).getBytes();
// 从packet 对象获取数据来源的地址 和 端口
DatagramPacket packetToClient = new DatagramPacket(sendedContent, sendedContent.length, packet.getAddress(), packet.getPort());
datagramSocket.send(packetToClient);
}
}
client
package com.javabasic.socket;
import java.io.IOException;
import java.net.*;
public class UDPClient {
public static void main(String[] args) throws IOException {
DatagramSocket socket = new DatagramSocket();
byte[] buff = "Hello world".getBytes();
InetAddress address = InetAddress.getByName("127.0.0.1");
DatagramPacket packet = new DatagramPacket(buff, buff.length, address, 65001);
socket.send(packet);
byte[] data = new byte[100];
DatagramPacket receivePacket = new DatagramPacket(data, data.length);
socket.receive(receivePacket);
String content = new String(receivePacket.getData(), 0, receivePacket.getLength());
System.out.println(content);
}
}