节作业一二三小注 )
Posted 朱呀朱-
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了节作业一二三小注 )相关的知识,希望对你有一定的参考价值。
Java-Day-29
UDP 网络通信编程 ( 了解 )
基本介绍
-
类 DatagramSocket 和 DatagramPacket 实现了基于 UDP 协议网络程序
- DatagramSocket:数据报套接字
- DatagramPacket:数据包 / 数据报
-
UDP 数据报通过数据报套接字 DatagramSocket 发送和接收,系统不保证 UDP 数据报一定能够安全送到目的地,也不能确定什么时候可以抵达 ( 所以是不可靠的 )
-
DatagramPacket 对象封装了 UDP 数据报,在数据报中包含了发送端的 IP 地址和端口号以及接收端的 IP 地址和端口号
-
UDP 协议中每个数据报都给出了完整的地址信息,因此无须建立发送方和接收方的连接
-
UDP 说明:
-
程序 / 发送端 ( 内含 DatagramSocket ) —— DatagramPacket ( 内含数据、ip、端口等 ) ——> 程序 / 接收端 ( 内含 DatagramSocket )
-
没有明确的服务端和客户端 ( 因为没有建立连接 ),演变成数据的发送端和接收端
-
接收数据和发送数据是通过 DatagramSocket 对象完成
-
将数据封装到 DatagramPacket 对象 ( 装包 ),然后发送
-
当接收到 DatagramPacket 对象,需要进行拆包,取出数据
-
DatagramSocket 可以指定在哪个端口接收数据
-
-
基本流程:
- 核心的两个类 / 对象 DatagramSocket 与 DatagramPacket
- 建立发送端,接收端
- 发送数据前,建立数据包 / 报 DatagramPacket 对象
- 调用 DatagramSocket 的发送、接收方法
- 关闭 DatagramSocket 释放资源
应用案例
-
编写一个接收端 A 和一个发送端 B
-
接收端 A 在 9999 端口等待接收数据 ( receive )
-
发送端 B 向接收端 A 发送数据 “ hello 哇 ”
-
接收端 A 接收到发送端 B 发送的数据,回复 " 你也 hello 哇 " 再退出
-
发送端 B 接收回复的数据再退出
-
接收端 A:UDPReceiver_A
public class UDPReceiver_A public static void main(String[] args) throws IOException // 1. 创建一个DatagramSocket对象,准备在9999接收数据 DatagramSocket socket = new DatagramSocket(9999); // 2. 构建一个DatagramPacket对象,准备接收数据 // 在前面讲解 UDP 协议时,老师说过一个数据包,最大是64K // byte[] buf = new byte[64 * 1024]; byte[] buf = new byte[1024]; // 题目的一句话,那1024就足够了 DatagramPacket packet = new DatagramPacket(buf, buf.length); // 3. 调用接收方法,通过网络传输的 DatagramPacket 对象 // 填充到 packet 对象 // 注意:当有数据包发送到 9999 端口时,就会接收到数据 // 如果没有数据包发送到本机的 9999 端口,就会阻塞等待 System.out.println("接收端A等待接收数据中......"); socket.receive(packet); // 4. 可以把 packet 进行拆包,取出数据并显示 int length = packet.getLength(); // 实际接收的数据字节长度(实际不一定有1024) byte[] data = packet.getData(); // 接收到数据 String s = new String(data, 0, length); System.out.println(s); // 5. 回复信息给B端 data = "你也 hello 哇".getBytes(); // new DatagramPacket(发送内容(字节数组),长度,主机(IP),端口) // InetAddress.getLocalHost() 是指定了自己给自己发,实际上这种情况都少 ---- 主机IP在命令行 ipconfig 自行查看 packet = new DatagramPacket(data, data.length, InetAddress.getByName("10.103.0.241"), 9998); socket.send(packet); // 发送 // 关闭资源 socket.close(); System.out.println("A端已退出");
-
发送端 B:UDPSender_B
public class UDPSender_B public static void main(String[] args) throws IOException // 1. 创建 DatagramSocket 对象,准备发送和接收数据 // 因为是另一端,所以不能和A用一个端口,packet里面有存对方的端口,若是都为9999就乱了 DatagramSocket socket = new DatagramSocket(9998); // 2. 将需要发送的数据,封装到 DatagramPacket 对象 byte[] data = "hello 哇".getBytes(); // new DatagramPacket(发送内容(字节数组),长度,主机(IP),端口) // InetAddress.getLocalHost() 是指定了自己给自己发,实际上这种情况都少 ---- 主机IP在命令行 ipconfig 自行查看 DatagramPacket packet = new DatagramPacket(data, data.length, InetAddress.getByName("10.103.0.241"), 9999); socket.send(packet); // 3. 接收从A端回复的信息 (A前部分代码) byte[] buf = new byte[1024]; // 题目的一句话,那1024就足够了 packet = new DatagramPacket(buf, buf.length); socket.receive(packet); int length = packet.getLength(); // 实际接收的数据字节长度(实际不一定有1024) data = packet.getData(); // 接收到数据 String s = new String(data, 0, length); System.out.println(s); // 关闭资源 socket.close(); System.out.println("B端已退出");
章节作业
-
题目一
-
使用字符流的方式,编写一个客户端程序和服务端程序
-
客户端发送 " name ",服务端接收到后,返回 " 我是 zyz "
-
客户端发送 " hobby ",服务端接收到后,返回 " 编写 java程序 "
-
不是这两个问题,回复 " 你说啥哩 "
-
服务端:
public class Homework01Server public static void main(String[] args) throws Exception ServerSocket serverSocket = new ServerSocket(8888); System.out.println("服务端8888端口监听等待......"); Socket socket = serverSocket.accept(); InputStream inputStream = socket.getInputStream(); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); String s = bufferedReader.readLine(); // 写入的用newLine结束,收到的用readLine结束 System.out.println(s); String answer = ""; if ("name".equals(s)) answer = "我是zyz"; else if ("hobby".equals(s)) answer = "编写java程序"; else answer = "你说啥嘞"; // 读取后回复 OutputStream outputStream = socket.getOutputStream(); BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream)); bufferedWriter.write(answer); bufferedWriter.newLine(); // 插入换行符,表示回复内容的结束 bufferedWriter.flush(); // 注意别忘了手动的 flush // 关闭其他资源 socket.close(); serverSocket.close(); bufferedReader.close(); bufferedWriter.close();
-
客户端:
public class Homework01Client public static void main(String[] args) throws Exception Socket socket = new Socket(InetAddress.getLocalHost(), 8888); OutputStream outputStream = socket.getOutputStream(); // 写入到数据通道,用字符流 BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream)); // 从键盘读取用户的问题 Scanner scanner = new Scanner(System.in); System.out.println("请输入你的问题"); String question = scanner.next(); bufferedWriter.write(question); // 通过bufferedWriter将问题写到数据通道 bufferedWriter.newLine(); //插入换行符表示内容接收(注意:对方要用readLine) bufferedWriter.flush(); // 获取和socket关联的输入流,读取数据(字符)并显示 InputStream inputStream = socket.getInputStream(); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); String s = bufferedReader.readLine(); System.out.println(s); bufferedReader.close(); bufferedWriter.close(); socket.close(); System.out.println("客户端退出......");
-
-
题目二
-
编写一个接收端 A 和一个客户端 B,使用 UDP 协议完成
-
接收端在 8888 端口等待接收数据 ( receive )
-
发送端向接收端发送数据 " 四大名著是哪些子 "
-
接收端接收到发送端发送的问题后,返回 “ 四大名著是 《 西游记 》、《 水浒传 》...... ”,否则返回 " what ? "
-
接收端和发送端程序退出
-
接收端:
public class Homework02ReceiverA public static void main(String[] args) throws IOException // 1. 创建一个DatagramSocket对象,准备在9999接收数据 DatagramSocket socket = new DatagramSocket(9999); // 2. 构建一个DatagramPacket对象,准备接收数据 byte[] buf = new byte[1024]; // 题目的一句话,那1024就足够了 DatagramPacket packet = new DatagramPacket(buf, buf.length); // 3. 调用接收方法,通过网络传输的 DatagramPacket 对象填充到 packet 对象 // 注意:当有数据包发送到 9999 端口时,就会接收到数据,否则就阻塞等待 System.out.println("接收端A等待接收数据中......"); socket.receive(packet); // 4. 可以把 packet 进行拆包,取出数据并显示 int length = packet.getLength(); // 实际接收的数据字节长度 byte[] data = packet.getData(); // 接收到数据 String s = new String(data, 0, length); // 字符串读出 String answer = ""; // 初始化回复数据 // 判断接收到的信息是什么 if ("四大名著是哪些子".equals(s)) answer = "四大名著是 《 西游记 》、《 水浒传 》......"; else answer = "what ?"; // 5. 回复信息给B端 data = answer.getBytes(); // new DatagramPacket(发送内容(字节数组),长度,主机(IP),端口) packet = new DatagramPacket(data, data.length, InetAddress.getByName("10.105.15.16"), 9998); socket.send(packet); // 发送 // 关闭资源 socket.close(); System.out.println("A端已退出");
-
发送端:
public class Homework02SenderB public static void main(String[] args) throws IOException // 1. 创建 DatagramSocket 对象,准备发送和接收数据 DatagramSocket socket = new DatagramSocket(9998); // 2. 将需要发送的数据,封装到 DatagramPacket 对象 Scanner scanner = new Scanner(System.in); System.out.println("请输入你的问题: "); String question = scanner.next(); byte[] data = question.getBytes(); // new DatagramPacket(发送内容(字节数组),长度,主机(IP),端口) DatagramPacket packet = new DatagramPacket(data, data.length, InetAddress.getByName("10.105.15.16"), 9999); socket.send(packet); // 3. 接收从A端回复的信息 (A前部分代码) byte[] buf = new byte[1024]; // 题目的一句话,那1024就足够了 packet = new DatagramPacket(buf, buf.length); socket.receive(packet); int length = packet.getLength(); // 实际接收的数据字节长度(实际不一定有1024) data = packet.getData(); // 接收到数据 String s = new String(data, 0, length); System.out.println(s); // 关闭资源 socket.close(); System.out.println("B端已退出");
- 注意:本机在 InetAddress.getByName 填写 IP 时,因为随机分配,所以 IP 会变化,要先 ipconfig 查下
-
-
题目三
-
编写客户端程序和服务器端程序
-
客户端可以输入一个音乐文件名,比如:解脱
-
服务器端收到音乐名后,可以给客户端返回这个音乐文件,如果服务器端没有这个文件,返回一个默认的音乐即可
-
客户端收到文件后,保存到本地 e:\\\\
-
提示:该程序可以使用 StreamUtils.java ( 此题只用了第一个转为字节数组的方法 )
public class StreamUtils /** * 功能:将输入流转换成byte[],即可以把文件的内容读入到byte[] */ public static byte[] streamToByteArray(InputStream is) throws Exception ByteArrayOutputStream bos = new ByteArrayOutputStream(); //创建输出流对象 byte[] b = new byte[1024]; // 字节数组 int len; while((len = is.read(b)) != -1) // 循环读取 bos.write(b, 0, len); // 把读取到的数据写入bos byte[] array = bos.toByteArray(); // 然后将bos转成字节数组(就是将图片转成程序内文件字节数组的过程) bos.close(); return array; public static String streamToString(InputStream is) throws Exception /** * 功能:输入流数据直接转成字符串 */ BufferedReader reader = new BufferedReader(new InputStreamReader(is)); StringBuilder builder = new StringBuilder(); String line; while ((line = reader.readLine()) != null) builder.append(line + "\\r\\n"); return builder.toString();
-
本质:其实就是指定下载文件的应用
-
服务端
public class Homework03Server public static void main(String[] args) throws Exception // 1. 监听 9999 端口,等待客户端连接 ServerSocket serverSocket = new ServerSocket(9999); // 2. 等待客户端连接 System.out.println("服务端,在9999端口监听,等待下载文件"); Socket socket = serverSocket.accept(); // 3. 读取客户端发送的要下载的文件名 InputStream inputStream = socket.getInputStream(); byte[] bytes = new byte[1024]; int readLen = 0; String downLoadFileName = ""; // 这里用while循环是考虑到将来客户端发送的数据较大的情况 while ((readLen = inputStream.read(bytes)) != -1) downLoadFileName += new String(bytes, 0, readLen); System.out.println("客户端希望下载的文件名为 = " + downLoadFileName); String resFileName = ""; if ("解脱".equals(downLoadFileName)) resFileName = "src\\\\main\\\\webapp\\\\img\\\\解脱.mp3"; else resFileName = "src\\\\main\\\\webapp\\\\img\\\\默认.mp3"; // 创建一个输入流,来读取文件 BufferedInputStream bis = new BufferedInputStream(new FileInputStream(resFileName)); // 使用工具类读取文件到一个字节数组中 byte[] bytes1 = StreamUtils.streamToByteArray(bis); // 输入流转成字节数组 // 得到Socket关联的输出流 BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream()); // 写入到数据通道,返回给客户端 bos.write(bytes1); socket.shutdownOutput(); // 设置结束标记,单方面关闭输入流,socket没有关闭 // 关闭相关的资源 bis.close(); inputStream.close(); socket.close(); serverSocket.close(); System.out.println("服务端已退出......");
-
客户端
public class Homework03Client public static void main(String[] args) throws Exception // 1. 用户输入,指定下载文件名 Scanner scanner = new Scanner(System.in); System.out.println("请输入下载文件名"); String downloadFileName = scanner.next(); // 2. 连接服务端,准备发送 Socket socket = new Socket(InetAddress.getLocalHost(), 9999); // 3. 获取和 Socket关联的输出流,输出文件名 OutputStream outputStream = socket.getOutputStream(); outputStream.write(downloadFileName.getBytes()); // 设置写入结束的标志(否则服务端的while循环不知道结束) socket.shutdownOutput(); // 4. 读取服务端返回的文件(字节数据),即获取刚才输入的想下载的文件 BufferedInputStream bis = new BufferedInputStream(socket.getInputStream()); byte[] bytes = StreamUtils.streamToByteArray(bis); // 接收InputStream转换、组装成字节数组 // 5. 得到一个输出流,准备将 bytes 写入到磁盘文件 String filePath = "e:\\\\" + downloadFileName + ".mp3"; // 路径实际是自行设置 BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(filePath)); bos.write(bytes); bos.close(); bis.close(); outputStream.close(); socket.close(); System.out.println("客户端下载完毕,正确退出......");
-
-
小注
-
close():套接字整个关闭
-
shutdown..put():告诉连接的另一端,我已完成所有数据的发送,同时还要保持接收数据的能力 ( 将输入或输出相互独立的关闭 ) —— 字节流使用
-
flush():手动刷新,刷后的结尾要 close 整个关闭—— 字符流使用 ( 文件较大,用到了缓冲区,即内存,所以要将其中内容强制写入 )
- 字符:一般 flush 前还要 newLine 插入一个换行符表结束
- 字节:flush 可不写 ( 因为不管写不写都会把数据保存到字节流上 ) ,但后面必须要 socket.shutdownOutput() 写入结束标记
-
2021年春季学期-信号与系统-第十三次作业参考答案-第三小题
本文是 2021年春季学期-信号与系统-第十三次作业参考答案 中各小题答案。
§03 第三小题
3. 离散时间系统如下图所示:
(1)求该系统的传递函数
H
(
z
)
H\\left( z \\right)
H(z);
(2)设系统的激励为:
x
[
n
]
=
[
(
−
1
)
n
+
(
−
2
)
n
]
u
[
n
]
x\\left[ n \\right] = \\left[ {\\left( { - 1} \\right)^n + \\left( { - 2} \\right)^n } \\right]u\\left[ n \\right]
x[n]=[(−1)n+(−2)n]u[n] 用z变换求该系统的零状态响应;
(3)已知:
x
[
n
]
=
δ
[
n
]
,
y
[
0
]
=
1
,
y
[
−
1
]
=
−
1
x\\left[ n \\right] = \\delta \\left[ n \\right],\\,\\,y\\left[ 0 \\right] = 1,\\,\\,y\\left[ { - 1} \\right] = - 1
x[n]=δ[n],y[0]=1,y[−1]=−1 用z变换求该系统的零输入相应;
提示:(2),(3)两步请参见第五章[5.7.2]中内容
▓ 求解:
(1)第一小问
(1) 通过设立中间变量W(z)建立两个方程:
系统的传递函数为:
Y ( z ) X ( z ) = 4 + 5 z − 1 1 − 3 z − 1 + 2 z − 2 = 4 z 2 + 5 z z 2 − 3 z + 2 {{Y\\left( z \\right)} \\over {X\\left( z \\right)}} = {{4 + 5z^{ - 1} } \\over {1 - 3z^{ - 1} + 2z^{ - 2} }}\\, = {{4z^2 + 5z} \\over {z^2 - 3z + 2}} X(z)Y(z)=1−3z−1+2z−24+5z−1=z2−3z+24z2+5z
(2)第二小问
(2) 系统输入信号的z变换:
X ( z ) = z z + 1 + z z + 2 X\\left( z \\right) = {z \\over {z + 1}} + {z \\over {z + 2}} X(z)=z+1z+z+2z
Y ( z ) = H ( z ) ⋅ X ( z ) = 4 z 2 + 5 z z 2 − 3 z + 2 ⋅ ( z z + 1 + z z + 2 ) Y\\left( z \\right) = H\\left( z \\right) \\cdot X\\left( z \\right) = {{4z^2 + 5z} \\over {z^2 - 3z + 2}} \\cdot \\left( {{z \\over {z + 1}} + {z \\over {z + 2}}} \\right) Y(z)=H(z)⋅X(z)=z2−3z+24z2+5z⋅(z+1z+z+2z) = 8 z 4 + 22 z 3 + 15 z 2 z 4 − 5 z 2 + 4 = z 2 ( 2 z + 3 ) ( 4 z + 5 ) ( z − 1 ) ( z − 2 ) ( z + 2 ) ( z + 1 ) = {{8z^4 + 22z^3 + 15z^2 } \\over {z^4 - 5z^2 + 4}} = {{z^2 \\left( {2z + 3} \\right)\\left( {4z + 5} \\right)} \\over {\\left( {z - 1} \\right)\\left( {z - 2} \\right)\\left( {z + 2} \\right)\\left( {z + 1} \\right)}} =z4−5z2+48z4+22z3+15z2=(z−1)(z−2)(z+2)(z+1)z2(2z+3)(4z+5) = − 15 2 z z − 1 + 15 1 6 z z − 2 + 1 2 z z + 2 + − 1 6 z z + 1 = {{ - {{15} \\over 2}z} \\over {z - 1}} + {{15{1 \\over 6}z} \\over {z - 2}} + {{{1 \\over 2}z} \\over {z + 2}} + {{ - {1 \\over 6}z} \\over {z + 1}} =z−1−215z+z−21561z+z+221z+z+1−61z
>>iztrans(ans)'
ans=(-2)^n/2 -(-1)^n/6 +(91*2^n)/6 -15/2
系统的零状态响应:
y [ n ] = − 15 2 + 1 2 ( − 2 ) n − 1 6 ( − 1 ) n + 91 6 ⋅ 2 n , n ≥ 0 y\\left[ n \\right] = - {{15} \\over 2} + {1 \\over 2}\\left( { - 2} \\right)^n - {1 \\over 6}\\left( { - 1} \\right)^n + {{91} \\over 6} \\cdot 2^n ,\\,\\,\\,\\,n \\ge 0 y[n]=−215+21(−2)n−6以上是关于节作业一二三小注 )的主要内容,如果未能解决你的问题,请参考以下文章
2021年春季学期-信号与系统-第十四次作业参考答案-第三小题参考答案
2021年春季学期-信号与系统-第十三次作业参考答案-第三小题