宠物网站建设论文总结,辽宁建设工程信息网保函保险服务模块,属于建筑施工企业会计存货的是,海口企业网站建设目录
一、网络编程基础
1.1 为什么需要网络编程#xff1f;——丰富的网络资源
二、什么是网络编程?
三、网络编程中的基本概念
3.2 请求和响应 3.3 客户端和服务端 常见的客户端服务端模型
四、Socket套接字
五、通信模型
5.1 Java数据报套接字通信模型
5.2 Java流…目录
一、网络编程基础
1.1 为什么需要网络编程——丰富的网络资源
二、什么是网络编程?
三、网络编程中的基本概念
3.2 请求和响应 3.3 客户端和服务端 常见的客户端服务端模型
四、Socket套接字
五、通信模型
5.1 Java数据报套接字通信模型
5.2 Java流套接字通信模型 Socket编程注意事项
5.3 UDP数据报套接字编程 示例一
示例二 一、网络编程基础 1.1 为什么需要网络编程——丰富的网络资源 用户在浏览器中打开在线视频网站如优酷看视频实质是通过网络获取到网络上的一个视频资源。 与本地打开视频文件类似只是视频文件这个资源的来源是网络。 相比本地资源来说网络提供了更为丰富的网络资源 所谓的网络资源其实就是在网络中可以获取的各种数据资源。 而所有的网络资源都是通过网络编程来进行数据传输的。 二、什么是网络编程? 网络编程指网络上的主机通过 不同的进程 以编程的方式实现 网络通信或称为网络数据传输 。 当然我们只要满足 进程 不同就行所以即便是同一个主机只要是不同进程基于网络来传输数据 也属于网络编程。 特殊的对于开发来说在条件有限的情况下一般也都是在一个主机中运行多个进程来完成网络编程。 但是我们一定要明确我们的目的是提供网络上不同主机基于网络来传输数据资源 进程A编程来获取网络资源 进程B编程来提供网络资源 三、网络编程中的基本概念
3.1 发送端和接收端
在一次网络数据传输时 发送端 数据的 发送方进程 称为发送端。发送端主机即网络通信中的源主机。 接收端 数据的 接收方进程 称为接收端。接收端主机即网络通信中的目的主机。 收发端 发送端和接收端两端也简称为收发端。 注意发送端和接收端只是相对的只是一次网络数据传输产生数据流向后的概念。 3.2 请求和响应 一般来说获取一个网络资源涉及到两次网络数据传输 第一次请求数据的发送 第二次响应数据的发送。 好比在快餐店点一份炒饭 先要发起请求点一份炒饭再有快餐店提供的对应响应提供一份炒饭 3.3 客户端和服务端 服务端 在常见的网络数据传输场景下把 提供服务 的一方进程称为服务端可以提供对外服务。 客户端 获取服务 的一方进程称为客户端。 对于服务来说一般是提供 客户端获取服务资源 客户端保存资源在服务端 好比在银行办事 银行提供存款服务用户客户端保存资源现金在银行服务端 银行提供取款服务用户客户端获取服务端资源银行替用户保管的现金 常见的客户端服务端模型
最常见的场景客户端是指给用户使用的程序服务端是提供用户服务的程序 1. 客户端先发送请求到服务端 2. 服务端根据请求数据执行相应的业务处理 3. 服务端返回响应发送业务处理结果 4. 客户端根据响应数据展示处理结果展示获取的资源或提示保存资源的处理结果 四、Socket套接字 概念 Socket 套接字是由系统提供用于网络通信的技术是基于 TCP/IP 协议的网络通信的基本操作单元。 基于Socket套接字的网络程序开发就是网络编程。 分类 Socket 套接字主要针对传输层协议划分为如下三类 4.1 流套接字 使用传输层 TCP 协议 TCP 即 Transmission Control Protocol 传输控制协议传输层协议。 以下为 TCP 的特点细节后续再学习 有连接 可靠传输 面向字节流 有接收缓冲区也有发送缓冲区 大小不限 对于字节流来说可以简单的理解为传输数据是基于 IO 流流式数据的特征就是在 IO 流没有关闭的情况下是无边界的数据可以多次发送也可以分开多次接收。 4.2. 数据报套接字 使用传输层 UDP 协议 UDP 即 User Datagram Protocol 用户数据报协议传输层协议。 以下为 UDP 的特点细节后续再学习 无连接 不可靠传输 面向数据报 有接收缓冲区无发送缓冲区 大小受限一次最多传输64k 对于数据报来说可以简单的理解为传输数据是一块一块的发送一块数据假如 100 个字节必须一次发送接收也必须一次接收100 个字节而不能分 100 次每次接收 1 个字节。 4.3 原始套接字 原始套接字用于自定义传输层协议用于读写内核没有处理的 IP 协议数据。 我们不学习原始套接字简单了解即可。 五、通信模型
5.1 Java数据报套接字通信模型 对于 UDP 协议来说具有无连接面向数据报的特征即每次都是没有建立连接并且一次发送全部数据报一次接收全部的数据报。 java 中使用 UDP 协议通信主要基于 DatagramSocket 类来创建数据报套接字并使用 DatagramPacket 作为发送或接收的 UDP 数据报。对于一次发送及接收 UDP 数据报的流程如下 以上只是一次发送端的 UDP 数据报发送及接收端的数据报接收并没有返回的数据。也就是只有请求没有响应。对于一个服务端来说重要的是提供多个客户端的请求处理及响应流程如下 5.2 Java流套接字通信模型 Socket编程注意事项 1. 客户端和服务端开发时经常是基于一个主机开启两个进程作为客户端和服务端但真实的场 景一般都是不同主机。 2. 注意目的 IP 和目的端口号标识了一次数据传输时要发送数据的终点主机和进程 3. Socket 编程我们是使用流套接字和数据报套接字基于传输层的 TCP 或 UDP 协议但应用层协议 也需要考虑这块我们在后续来说明如何设计应用层协议。 4. 关于端口被占用的问题 如果一个进程 A 已经绑定了一个端口再启动一个进程 B 绑定该端口就会报错这种情况也叫端 口被占用。对于 java 进程来说端口被占用的常见报错信息如下 此时需要检查进程B绑定的是哪个端口再查看该端口被哪个进程占用。以下为通过端口号查进程的方式 在cmd输入 netstat -ano | findstr 端口号 则可以显示对应进程的pid。如以下命令显 示了 8888 进程的 pid 在任务管理器中通过pid查找进程 解决端口被占用的问题 如果占用端口的进程A不需要运行就可以关闭A后再启动需要绑定该端口的进程B 如果需要运行A进程则可以修改进程B的绑定端口换为其他没有使用的端口。 5.3 UDP数据报套接字编程 DatagramSocket API DatagramSocket 是 UDP Socket 用于发送和接收 UDP 数据报。 DatagramSocket 构造方法 DatagramSocket 方法 DatagramPacket API DatagramPacket 是 UDP Socket 发送和接收的数据报。 DatagramPacket 构造方法 DatagramPacket 方法 构造UDP发送的数据报时需要传入 SocketAddress 该对象可以使用 InetSocketAddress 来创 建。 InetSocketAddress API InetSocketAddress SocketAddress 的子类 构造方法 示例一 实现一个基于TCP的回显服务 客户端 mport java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;public class TCPEchoClient {// 定义一个用于客户端的Socket对象private Socket clientSocket;/*** 初始化客户端的Socket** param serverIp 服务器IP地址* param serverPort 服务器的端口号* throws IOException*/public TCPEchoClient (String serverIp, int serverPort) throws IOException {this.clientSocket new Socket(serverIp, serverPort);}public void start () throws IOException {System.out.println(客户端已启动...);// 获取Socket中的输入输出流try (InputStream inputStream clientSocket.getInputStream();OutputStream outputStream clientSocket.getOutputStream()) {// 循环处理用户的输入while (true) {System.out.println(-);// 接收用户的输入内容Scanner requestScanner new Scanner(System.in);String request requestScanner.nextLine();// 发送用户的请求PrintWriter printWriter new PrintWriter(outputStream);printWriter.println(request);// 强制刷新缓冲区printWriter.flush();// 接收服务器的响应Scanner responseScanner new Scanner(inputStream);// 获取响应数据String response responseScanner.nextLine();// 打印响应内容System.out.println(接收到服务器的响应 response);}} catch (IOException e) {e.printStackTrace();} finally {clientSocket.close();}}public static void main(String[] args) throws IOException {TCPEchoClient client new TCPEchoClient(127.0.0.1, 9999);client.start();}
} 服务端 import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ProtocolException;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.MessageFormat;
import java.util.Scanner;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;/*** 基于TCP的服务器程序* Date 2023-05-23*/
public class TCPEchoServer {// 声明一个用于服务端的Socket对象private ServerSocket server;/*** 通过指定端口号实例化服务** param port 端口号* throws IOException*/public TCPEchoServer(int port) throws IOException {if (port 1025 || port 65535) {throw new RuntimeException(端口号要在 1025 ~ 65535之间.);}// 实例化ServerSocket并指定端口号this.server new ServerSocket(port);}public void start() throws IOException {System.out.println(服务器启动成功...);// 创建一个线程池ThreadPoolExecutor poolExecutor new ThreadPoolExecutor(3, 10, 1, TimeUnit.SECONDS,new LinkedBlockingQueue(10));// 循环接收客户端的连接while (true) {Socket clientSocket server.accept();// 每接收到一个新连接请求就创建一个新的子线程
// Thread thread new Thread(() - {
// // 处理Socket中的数据
// try {
// processConnections(clientSocket);
// } catch (IOException e) {
// e.printStackTrace();
// }
// });
// // 启动线程
// thread.start();// 提交任务到线程池中poolExecutor.submit(() - {try {processConnections(clientSocket);} catch (IOException e) {e.printStackTrace();}});}}// 处理数据private void processConnections(Socket clientSocket) throws IOException {// 打印日志String clientInfo MessageFormat.format([{0}:{1}] 客户端已上线, clientSocket.getInetAddress(),clientSocket.getPort());System.out.println(clientInfo);// 处理数据之前要获取一下输入输出流try (InputStream inputStream clientSocket.getInputStream();OutputStream outputStream clientSocket.getOutputStream()) {// 循环处理用户的请求while (true) {// 通过Scanner读取用户请求中的数据Scanner requestScanner new Scanner(inputStream);if (!requestScanner.hasNextLine()) {// 日志clientInfo MessageFormat.format([{0}:{1}] 客户端已下线., clientSocket.getInetAddress(),clientSocket.getPort());System.out.println(clientInfo);break;}// 获取真实的用户请求数据String request requestScanner.nextLine();// 根据请求计算响应String response process(request);// 把响应写回客户端PrintWriter printWriter new PrintWriter(outputStream);// 写入输出流printWriter.println(response);// 强制刷新缓冲区printWriter.flush();// 打印日志clientInfo MessageFormat.format([{0}:{1}], request: {2}, response: {3},clientSocket.getInetAddress(), clientSocket.getPort(), request, response);System.out.println(clientInfo);}} catch (IOException e) {e.printStackTrace();} finally {clientSocket.close();}}private String process(String request) {System.out.println(收到新消息 request);Scanner scanner new Scanner(System.in);String response scanner.nextLine();return response;}public static void main(String[] args) throws IOException {TCPEchoServer server new TCPEchoServer(9999);server.start();}
}示例二 实现一个基于UDP的回显服务 客户端 import java.io.IOException;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;/*** Date 2023-05-20*/
public class UDPEchoClient {// 定义一个用于客户端的DatagramSocketprivate DatagramSocket client;// 定义服务器的IP地址private String serverIp;// 定义服务器的端口号private int port;private SocketAddress address;/*** 构造方法,指定服务器的Ip地址和端口号** param serverIp 服务器IP* param port 端口号*/public UDPEchoClient (String serverIp, int port) throws SocketException {this.client new DatagramSocket();this.serverIp serverIp;this.port port;this.address new InetSocketAddress(serverIp, port);}public void start () throws IOException {System.out.println(客户端已启动.);// 循环接收用户的输入Scanner scanner new Scanner(System.in);while (true) {System.out.println(-);// 接收用户输入String request scanner.next();// 1. 把请求内容包装成DatagramPacketDatagramPacket requestPacket new DatagramPacket(request.getBytes(StandardCharsets.UTF_8),request.getBytes().length, address);// 2. 发送数据client.send(requestPacket);// 3. 接收响应DatagramPacket responsePacket new DatagramPacket(new byte[1024], 1024);// 4. 在receive方法中填充响应数据client.receive(responsePacket);// 5. 解析响应数据String response new String(responsePacket.getData(), 0, responsePacket.getLength(), UTF-8);// 6. 打印日志System.out.printf(request: %s, response: %s.\n, request, response);}}public static void main(String[] args) throws IOException {UDPEchoClient client new UDPEchoClient(127.0.0.1, 9999);// 启动服务client.start();}}服务端 import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.nio.charset.StandardCharsets;/*** UDP 回显服务器** Date 2023-05-20*/
public class UDPEchoServer {// 定义一个用于服务器端的DatagramSocketprivate DatagramSocket server;/*** 构造方法完成服务器的初始化* param port 端口号*/public UDPEchoServer (int port) throws Exception {if (port 65535 || port 1024) {throw new Exception(端口号必须在1024 ~ 65535之间);}// 初始化服务器端的UDP服务this.server new DatagramSocket(port);}/*** 对外提供服务*/public void start () throws IOException {System.out.println(服务器已启动....);// 循环接收用户的请求while (true) {// 1. 创建一个用于接收请求数据的DatagramPacketDatagramPacket requestPacket new DatagramPacket(new byte[1024], 1024);// 2. 接收请求, 把真实的内容填充到requestPacketserver.receive(requestPacket);// 3. 从requestPacket获取数据String request new String(requestPacket.getData(), 0, requestPacket.getLength(), UTF-8);// 4. 根据请求获取响应String response processor (request);// 5. 把响应封装到DatagramPacketDatagramPacket responsePacket new DatagramPacket(response.getBytes(StandardCharsets.UTF_8),response.getBytes().length, requestPacket.getSocketAddress());// 6. 发送数据server.send(responsePacket);// 7. 打印日志System.out.printf([%s:%d] request: %s, response: %s.\n, requestPacket.getAddress().toString(),requestPacket.getPort(), request, response);}}public String processor(String request) {return request;}public static void main(String[] args) throws Exception {// 初始化服务器UDPEchoServer server new UDPEchoServer(9999);// 启动服务server.start();}}简单的字典功能 import java.io.IOException;
import java.util.HashMap;
import java.util.Map;/*** Date 2023-05-20*/
public class UDPDictServer extends UDPEchoServer{private MapString, String map new HashMap();/*** 构造方法完成服务器的初始化** param port 端口号*/public UDPDictServer(int port) throws Exception {super(port);// 初始化字典内容map.put(dog, 小狗);map.put(cat, 小猫);map.put(pig, 小猪);map.put(tiger, 大老虎);map.put(veryGood, 牛P);}Overridepublic String processor(String request) {return map.getOrDefault(request, 查无此词);}public static void main(String[] args) throws Exception {UDPDictServer server new UDPDictServer(9999);server.start();}
}