鲁吼呀,胶己人!
文章目录
- JavaEE & 网络编程示例1 & UDP套接字数据报编程 ==> 一发一收
- 1. 协议分层(回顾)
- 2. 套接字 Socket
- 2.1 UDP与TCP两组协议的主要区别
- 2.1.1 UDP无连接,TCP有链接
- 2.1.2 UDP不可靠传输,TCP可靠传输
- 2.1.3 UDP面向数据报,TCP面向字节流
- 2.1.4 UDP与TCP 全双工
- 3. 网络编程示例1 ==> 一发一收
- 3.1 DatagramSocket 与 DatagramPacket
- 3.1.1 Socket对象
- 3.1.2 DatagramSocket的一些方法
- 3.1.3 DatagramPacket的一些方法
- 3.2 基于UDP 的 Socket 写一个简单的客户端服务器程序
- 3.2.1 服务器
- 3.2.1.1 读取请求并解析
- 3.2.1.2 计算请求信息为响应信息
- 3.2.1.3 将响应信息打包成【数据报】
- 3.2.1.4 响应数据报信息发送给客户端
- 3.2.1.5 打印日志
- 3.2.1.6 图片分析
- 3.2.2 客户端
- 3.2.2.1 控制台输入请求
- 3.2.2.2 请求信息打包成【数据报】
- 3.2.2.3 通过socket对象将【数据报】发送给服务器
- 3.2.2.4 等待服务器响应
- 3.2.2.5 提取数据报信息并打印日志
- 3.2.2.6 图片分析
- 3.2.3 测试与总结
- 3.3 socket文件怎么存储数据的
对于2 和 3 是操作系统内核封装的
对于4 和 5 是硬件和驱动控制的
程序员编写网络程序主要编写的是应用层代码
那么,我们就需要第下层协议的提供服务,即 应用层调用传输层提供的API
这些API是C / C++ 风格的,因为操作系统本身就是C / C++ 写的
系统给咱们提供了两组socket API
Destination User Prompter
Transmission Control Protocol
就比如说谈恋爱和结婚,结婚就是一种有效的抽象连接
如果我们的两台机器在通信的时候,需要单独保存记录两台机器的信息就是有连接,不需要则是无连接
小例子:
以上面的那个例子继续说:
我还记得我高中的时候,老人机发短信给我老爸,叫他来学校载我,结果我不知道我爸没收到,导致我等了2 - 3小时 T.T
TCP面向字节流:
UDP面向数据报:
单双工:一条路径,单向通信
全双工:一条路径,双向通信
例如马路:
在文件操作系统中,在文件操作的 时候提到,不是目录不是普通文件的文件
而socket文件并非对应到硬盘的某一个存储区,而是对应到网卡的一个硬件设备
打开命令行(win + R + cmd)输入ipconfig:
文件:
所以,要相进行网络通信,就需要socket文件对应的这个对象(内存中的变量)去搞事情,从而间接操控网卡
方法名 | 方法说明 |
---|---|
DatagramSocket() | 创建一个Socket,绑定本机任意一个空闲的端口 |
DatagramSocket(int port) | 创建一个Socket,绑定指定的端口(port) |
小例子:
方法名 | 方法说明 |
---|---|
void receive(DatagramPacket p) | 接受数据报并读取到已有数据报 |
void send(DatagramPacket p) | 发送数据报 |
void close() | 关闭socket文件(避免文件资源泄露,但是很少有关闭的时候,这也符合实际情况) |
方法名 | 方法说明 |
---|---|
DatagramPacket(byte[] buf, int length) | 成员buf取参数字节数组的头开始,长度length的部分 |
DatagramPacket(byte[] buf, int offset, int length, SocketAddress address) | 成员buf取参数为字节数组的头开始长度length的部分,并且传入offset(缓冲区偏移量)和socket地址 |
DatagramPacket(byte[] buf, int length, InetAddress address, int port) | 成员buf取参数为字节数组的头开始长度length的部分,并传入包装IP的InetAddress对象,和端口号 |
方法名 | 方法说明 |
---|---|
InetAddress getAddress() | 获取客户端or服务器的IP地址 |
int getPort() | 获取客户端or服务器的端口号 |
byte[] getData() | 获取数据报里的数据 |
接下来就是书写代码的环节了!
三个核心工作:
public UDPEchoServer(int port) throws SocketException {
this.socket = new DatagramSocket(port);
}
public void start() {
System.out.println("启动服务器成功");
//服务器一直工作 或者 等待客户端请求
//所以说才很少关闭~
while(true) {
//做那三件事!
}
}
再次重点强调【数据报】是什么
而我们只需要用socket对象与网卡进行联系,这样就能实现应用层和传输层的数据交换~
而UDP协议,数据传输的基本单位就是【数据报】!
public void start() throws IOException {
System.out.println("启动服务器成功");
//服务器一直工作 或者 等待客户端请求
while(true) {
DatagramPacket request = new DatagramPacket(new byte[1024], 1024);
//**************** 自带饭盒 ****************
socket.receive(request);//request --- 载体
//io操作都可能会有IOException异常
//盛饭,从网卡里面拿的请求,将其录入已存在的数据报里
String request = new String(requestPacket.getData(), 0, requestPacket.getLength());
}
}
死循环是因为一个服务器无时无刻都要尝试获取请求~
此时,如果还没有客户端发来的数据,咋办?
String response = process(request);
//计算该字符串的响应
public String process(String request) {
//回显服务器直接返回原值~
return request;
}
DatagramPacket responsePacket = new DatagramPacket(response.getBytes(),
response.getBytes().length,
requestPacket.getSocketAddress());
socket.send(responsePacket);
//发送数学报,数据报有客户端的信息,所以可以具体的转发到对方机器
//响应
System.out.printf("客户端[%s, %d], 发来请求[request]:%s, 其将收到响应[response]:%s\n",
requestPacket.getAddress(), requestPacket.getPort(),
request, response);
三个核心工作:
public class UDPEchoClient {
private DatagramSocket socket = null;
private String serverIP;
private int serverPort;
}
//确定服务器
public UDPEchoClient(String serverIP, int serverPort) throws SocketException {
this.socket = new DatagramSocket();
this.serverIP = serverIP;
this.serverPort = serverPort;
}
public void start() throws IOException {
//客户端输入信息
Scanner scanner = new Scanner(System.in);
while(true) {
System.out.print("-> ");
String request = scanner.nextLine();
//next方法以空格或者回车分割!
//控制台输入数据报的【主信息】
}
}
这里需要可以利用这个构造方法~
InetAddress对象就是IP的一种包装~
InetAddress.getByName,打包对应的IP地址
这里传入了serverIP,即服务器IP
不用理解太深,用就是了
DatagramPacket requestPacket = new DatagramPacket(request.getBytes(),
request.getBytes().length,
InetAddress.getByName(serverIP), serverPort);
//打包信息成数据报
//根据ip打包成InetAddress对象
socket.send(requestPacket);
//发送给服务器
DatagramPacket responsePacket = new DatagramPacket(new byte[1024], 1024);
//等待服务器返回响应
//而两个机器之间是通过数据报传输
socket.receive(responsePacket);
同样的,服务器返回前,要阻塞等待~
String response = new String(responsePacket.getData(), 0, responsePacket.getLength());
//获取数据报里面的响应信息!
System.out.printf("服务器[%s, %d], 收到请求[request]:%s, 发来响应[response]:%s\n", serverIP,
serverPort, request, response);
//打印日志
public static void main(String[] args) throws IOException {
UDPEchoServer udpEchoServer = new UDPEchoServer(9090);
udpEchoServer.start();
}
public static void main(String[] args) throws IOException {
UDPEchoClient udpEchoClient = new UDPEchoClient("10.61.10.239", 9090);
udpEchoClient.start();
}
对,没错,这是两个进程!
win + R + cmd + ipconfig
运行测试:
总结图示:
文章到此结束!谢谢观看 —>内容参考【比特科技】
可以叫我 小马,我可能写的不好或者有错误,但是一起加油鸭!后续会持续更新网络编程的相关博客,这个是个大家伙!
敬请期待!