目录
应用层
一、传输层的两个核心协议
二、有链接/无连接(是抽象的概念,是虚拟的/逻辑上的连接),例如要进行网络通信,物理上的连接(网线啥的)
三、可靠传输 vs 不可靠传输
四、面向字节流 vs 面向数据报
五、全双公 vs 半双工
六、回升服务器(重点)
应用层
操作系统提供的一组 API => socket API (传输层给应用层提供);socket 这个词的意思是插槽的意思,对应在主板上可以理解为主板上的一些接口。
一、传输层的两个核心协议
TCP协议 和 UDP协议这两个差别非常大。
- TCP 是有连接,可靠传输,面向字节流,全双工
- UDP 是无连接,不可靠传输,面向数据报,全双工
二、有链接/无连接(是抽象的概念,是虚拟的/逻辑上的连接),例如要进行网络通信,物理上的连接(网线啥的)
- 为什么TCP 是可靠的传输(有链接),而 UDP 是不可靠传输(无连接)。
对于 TCP 来说,TCP 协议中,就会保存对端的信息,例如 A和B通信,A和B先建立连接,让A保存B的信息,B保存A的信息(彼此之间知道,谁是和它连接的哪个)。
对于UDP来说,UDP协议本身,不保存对方的信息。就是无连接 。
三、可靠传输 vs 不可靠传输
网络上数据是非常容易出现丢失的情况(丢包),因为光信号/电信号,都可能受到外界的干扰。本来是传输0101,但是因为数据的丢包,其中有些bit位就被修改了,这样乱了的数据就会被识别出来,把这样的数据极可能传输不到原来的地方。
而且网络世界是通过 路由器/交换机 来进行联络的,路由器/交换机 类似于“十字路口”,它也会发生我们生活中十字路口堵车的情况,(在某个时间点,实际需要转发的数据超过了设备能转发的上线),就会容易发生数据丢包问题。
- 可靠传输的意思是,不能保证数据包 100% 的到达,而是尽可能的提高传输成功的概率。如果出现了丢包,能够感知到。
- 不可靠传输,只是把数据发出去,他到底是到了还是没到,他就不管了。
四、面向字节流 vs 面向数据报
面向字节流,读写数据的时候,是以字节为单位的
面向数据报,读写数据的时候,是以一个数据报为单位(不是字符为单位),一次必须读写一个 UDP 数据报,不能是半个。
五、全双公 vs 半双工
全双工:一个通信链路,支持 双向通信 (能读,也能写)
半双工:一个通信链路,只支持单向通信(只能读,或者只能写)
他们俩就像我们的一条公路,公路上的黄色线,就是车道的分割线。全双工就像是双向公路,这条路可以从A到B,也可以从B到A。半双工就像是单向公路,只能从A到B,或者是从B到A。
接下来就可以使用socket api 进行网络编程了
在计算机中“文件”通常是一个“广义的概念”,文件还能代指一些硬件设备(操作系统管理硬件设备,也是抽象成文件,统一管理的)。就像 网卡 抽象成 socket 文件,操作网卡的时候,流程和操作普通文件差不多, 打开 -> 读写 -> 关闭。
操作网卡,直接不好操作,把操作网卡当成操作 socket文件,就容易操作了。socket文件就相当于“网卡的遥控器”。
六、回升服务器(重点)
下面我们写一个回声服务器。回声服务器是一个客户端输入什么,服务器端什么任务都不做,直接返回客户端输入的内容
先说一下大致流程:
private DatagramSocket socket = null;
public UdpEchoServer01(int port) throws SocketException {
// 指定一个固定端口号,给服务器使用
socket = new DatagramSocket(port);
}
}
System.out.println("服务器启动");
while(true){
}
}
System.out.println("服务器启动");
while(true){
DatagramPacket requestPacket = new DatagramPacket(new byte[4096], 4096);
}
}
System.out.println("服务器启动");
while(true){
DatagramPacket requestPacket = new DatagramPacket(new byte[4096], 4096);
//////////// 使用接口给 requestPacket 这个数据报中传入客户端的请求
socket.receive(requestPacket);
}
}
System.out.println("服务器启动");
while(true){
DatagramPacket requestPacket = new DatagramPacket(new byte[4096], 4096);
socket.receive(requestPacket);
//////////////////////// 获取 requestPacket 中的 data
String request = new String(requestPacket.getData(), 0, requestPacket.getLength());
////////////// 这里无法使用,如果传入 getData().length 每次构造的长度都会是4096,会造成请求混乱
// String request = new String(requestPacket.getData(), 0, requestPacket.getData().length);
}
}
System.out.println("服务器启动");
while(true){
DatagramPacket requestPacket = new DatagramPacket(new byte[4096], 4096);
socket.receive(requestPacket);
String request = new String(requestPacket.getData(), 0, requestPacket.getLength());
//// 使用 response 接收响应
String response = process(request);
}
}
///// 服务器处理请求返回响应的函数
public String process(String request){
return request;
}
System.out.println("服务器启动");
while(true){
DatagramPacket requestPacket = new DatagramPacket(new byte[4096], 4096);
socket.receive(requestPacket);
String request = new String(requestPacket.getData(), 0, requestPacket.getLength());
String response = process(request);
///////////////// 直接使用 getSocketAdderss()
DatagramPacket responsePacket = new DatagramPacket(response.getBytes(),response.getBytes().length,
requestPacket.getSocketAddress());
/////////////// 使用 getAddress() 和 gerPort() 分别获取 IP 和 端口号
// DatagramPacket responsePacket = new DatagramPacket(response.getBytes(),response.getBytes().length,
// requestPacket.getAddress(), requestPacket.getPort());
}
}
public String process(String request){
return request;
}
System.out.println("服务器启动");
while(true){
DatagramPacket requestPacket = new DatagramPacket(new byte[4096], 4096);
socket.receive(requestPacket);
String request = new String(requestPacket.getData(), 0, requestPacket.getLength());
String response = process(request);
DatagramPacket responsePacket = new DatagramPacket(response.getBytes(),response.getBytes().length,
requestPacket.getSocketAddress());
////////// 把响应数据报返回给客户端
socket.send(responsePacket);
///////////// 打印一下服务器日志
System.out.printf("[%s:%d] req: %s resp: %s\\n", requestPacket.getAddress(), requestPacket.getPort(),
request, response);
}
}
public String process(String request){
return request;
}
网硕互联帮助中心





评论前必须登录!
注册