首先我们先了解一下网络原理中的TCP/IP五层协议:我们用平常生活中 买快递,收发快递
作为例子来描述让大家更好的理解这些知识
分别是
1.物理层 基础设施 ,不考虑其它
相当于我们的国道,高速公路,没有这些也就不存在通过快递的形式买卖商品
2.数据链路层 两个相邻节点之间的数据传输,不考虑其它
相对于两个相邻的快递站之间通过什么方法运输,比如用电动车,火车,飞机等方法
3.网络层 两个节点的数据规划,不考虑其它
相对于规划我们快递(数据)的路线,比如我的地点在深圳南山区,卖家地点在辽宁沈阳
这快递(数据)究竟是从 辽宁沈阳->北京->安徽->江西->深圳南山区
辽宁沈阳->天津->河南->江西->深圳南山区
辽宁沈阳->天津->江苏->江西->深圳南山区
。。。。。。
数据传递的路线是由网络层规划的
4.传输层 通信的起点和终点
相对于我们买快递时卖方只考虑起点,终点就行了,不考虑其它
5.应用层 传过去的数据怎么用
相对于我们生活中收到快递里的牙刷(数据)想用来刷牙也行,想用来洗澡也行
二:网络编程的概念:
我们的网络编程其实就是用代码实现多个 进程 之间的通信,由于进程之间有隔离性,我们网络编程就是通过进程的公共区域(网卡)来实现多个进程的相互通信
三:了解什么是客户端,服务器
客户端就是谁主动发送数据谁就是客户端 ,
客户端发送给服务器的数据也叫请求
服务器就是谁主动接收数据谁就是服务器 一般(7*24小时启动)
服务器给客户端返回的数据也叫响应
例如:我们在生活中去到一家烧烤店点了10串烤五花肉,我们主动发送10串烤五花肉给老板,我们就是客户端,
老板接收到客户端这一信息就马上去烤10串五花肉了,老板这就是服务器,并且客户端一般有非常多
四:客户端与服务器之间的交互方式
1. 一文一答: 客户端发送一个请求,服务器返回一个响应
常见的方式 浏览网页,手机点开app的功能都是
2.一文多答:客户端发送一个请求,服务器返回多个响应
常见的方式: 下载
3.多问一答:客户端发送多个请求,服务器返回一个响应
常见的方式: 上传
4.多问多答:客户端发送多个请求,服务器返回多个响应
常见的方式: 远程控制
五: 传输层提供的TCP/UDP协议
TCP:有连接,可靠传输,面向字节流,全双工
UDP:无连接,不可靠传输,面向数据报,全双工
有连接: 打电话,先建立连接,等待别人接了,才能通信
无连接:发微信,直接就发,不需要连接也能通信
可靠传输:数据接收方 有无收到数据 发送方有感知,生活中打电话就是可靠传输,对方有没有接收到我们的数据我们是知道的
不可靠传输:数据接收方 有无收到数据 发送放无感知,生活中发微信、QQ就是不可靠传输,我们发了信息对方有没有接收到,看到我们是不清楚的
面向字节流:InputStream抽象类
面向数据报:DatagramPacket类
全双工相对于打电话:发送方能发送数据,接收方同时也能返回数据
半双工相对于对讲机:发送方发送数据时,接收方不能返回数据
六:UDP的核心类
DatagramSocket:构造一个DatagramSocket就相当于打开了操作系统内核里的socket文件
打开之后就可以传数据了
七:写一个UDP版本的回显服务器-客户端(客户端发送什么,服务器返回什么)
服务器
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class UdpEchoServer {
// 要想创建 UDP 服务器, 首先要先打开一个 socket 文件.
private DatagramSocket socket = null;
public UdpEchoServer(int port) throws SocketException {
socket = new DatagramSocket(port);
}
// 启动服务器
public void start() throws IOException {
System.out.println("服务器启动!");
while (true) {
// 1. 读取客户端发来的请求.
DatagramPacket requestPacket = new DatagramPacket(new byte[4096], 4096);
socket.receive(requestPacket);
// 2. 对请求进行解析, 把 DatagramPacket 转成一个 String
String request = new String(requestPacket.getData(), 0, requestPacket.getLength());
// 3. 根据请求, 处理响应. 虽然咱们这是个回显服务器. 但是还是可以单独搞个方法来做这个事情.
String response = process(request);
// 4. 把响应构造成 DatagramPacket 对象.
// 构造响应对象, 要搞清楚, 对象要发给谁!! 谁给咱们发的请求, 就把响应发给谁~~~
DatagramPacket responsePacket = new DatagramPacket(response.getBytes(), response.getBytes().length,
requestPacket.getSocketAddress());
// 5. 把这个 DatagramPacket 对象返回给客户端.
socket.send(responsePacket);
System.out.printf("[%s:%d] req=%s; resp=%s\n", requestPacket.getAddress().toString(), requestPacket.getPort(),
request, response);
}
}
// 通过这个方法, 实现根据请求计算响应 这个过程.
// 由于是回显服务器, 所以不涉及到其他逻辑.
// 但是如果是其他服务器, 就可以在 process 里面, 来加上一些其他逻辑的处理.
public String process(String req) {
return req;
}
public static void main(String[] args) throws IOException {
// 真正启动服务器, 这个端口号说是随便写, 但是也有范围的. 0 -> 65535
// 但是一般来说 1024 以下的端口, 都是系统保留.
// 因此咱们自己写代码, 端口尽量还是选择 1024 以上, 65535 以下的.
UdpEchoServer server = new UdpEchoServer(8100);
server.start();
}
}
代码解析
private DatagramSocket socket = null;
//这里是构造方法
public UdpEchoServer(int port) throws SocketException {
socket = new DatagramSocket(port);
}
一:想要创建服务器首先打开socket文件,这里就相当于打开socket文件,
UdpEchoServer构造方法中的(int port)就是输入服务器的端口号,端口号是网络上的身份标识符,相当于我们的身份证,网络通信中可以通过端口号来确认将数据传给那个进程
// 1. 读取客户端发来的请求.
DatagramPacket requestPacket = new DatagramPacket(new byte[4096], 4096);
socket.receive(requestPacket);
二:读取客户端发来的请求:
我们是以数据报DatagramPacket类来传输数据的,所以我们先实例化一个DatagramPacket类
receive接收