Java进阶之旅-day05:网络编程
引言
在当今数字化的时代,网络编程在软件开发中扮演着至关重要的角色。Java 作为一门广泛应用的编程语言,提供了强大的网络编程能力。今天,我们深入学习了 Java 网络编程的基础知识,包括基本的通信架构、网络编程三要素、IP 地址、TCP 协议、UDP 通信等内容。接下来,我们将对这些知识点进行详细的总结。
基本的通信架构
在网络编程中,常见的通信架构有客户端 - 服务器(Client - Server,C/S)架构和浏览器 - 服务器(Browser - Server,B/S)架构。
C/S 架构
客户端 - 服务器架构是一种传统的网络通信模式。在这种架构中,客户端程序向服务器发送请求,服务器接收到请求后进行处理,并将处理结果返回给客户端。例如,我们使用的 QQ、微信等即时通讯软件就是典型的 C/S 架构应用。以下是一个简单的 C/S 架构 Java 示例,模拟客户端向服务器发送消息:
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;// 服务器端
class SimpleServer {public static void main(String[] args) {try (ServerSocket serverSocket = new ServerSocket(12345)) {System.out.println("Server is listening on port 12345");Socket socket = serverSocket.accept();BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));String message = in.readLine();System.out.println("Received from client: " + message);socket.close();} catch (IOException e) {e.printStackTrace();}}
}// 客户端
class SimpleClient {public static void main(String[] args) {try (Socket socket = new Socket("localhost", 12345);PrintWriter out = new PrintWriter(socket.getOutputStream(), true)) {String message = "Hello, Server!";out.println(message);} catch (IOException e) {e.printStackTrace();}}
}
B/S 架构
浏览器 - 服务器架构是一种基于 Web 技术的网络通信模式。在这种架构中,客户端只需要通过浏览器访问服务器上的网页,服务器将网页内容返回给浏览器进行显示。例如,我们日常使用的各种网站就是 B/S 架构的应用。以下是一个简单的 Java Servlet 示例模拟 B/S 架构的服务器端处理:
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;@WebServlet("/hello")
public class HelloServlet extends HttpServlet {protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.setContentType("text/html");PrintWriter out = response.getWriter();out.println("<html><body>");out.println("<h1>Hello, World!</h1>");out.println("</body></html>");}
}
网络编程三要素
网络编程的三要素包括 IP 地址、端口号和协议。
IP 地址
IP 地址是互联网协议地址的缩写,它是用于标识网络中设备的唯一标识符。通过 IP 地址,不同设备之间可以进行通信。
端口号
端口号是用于标识应用程序的数字。在一台设备上,可能同时运行着多个应用程序,每个应用程序通过不同的端口号来接收和发送数据。端口号的范围是 0 - 65535,其中 0 - 1023 通常被系统保留使用。
协议
协议是网络通信中双方必须遵循的规则和约定。常见的网络协议有 TCP(传输控制协议)和 UDP(用户数据报协议),我们将在后面详细介绍这两种协议。
IP 地址详解
IP 地址的作用
IP 地址的主要作用是在网络中唯一标识一台设备,使得不同设备之间能够进行通信。就像我们的家庭地址一样,通过 IP 地址,数据可以准确地从源设备传输到目标设备。
IP 地址的分类
IP 地址主要分为 IPv4 和 IPv6 两种类型。
IPv4
IPv4 是目前广泛使用的 IP 地址版本,它由 32 位二进制数组成,通常用点分十进制表示,例如 192.168.1.1。由于 IPv4 地址空间有限,随着互联网的发展,IPv4 地址已经逐渐耗尽。
IPv6
IPv6 是为了解决 IPv4 地址不足的问题而推出的新一代 IP 地址版本。它由 128 位二进制数组成,采用冒号十六进制表示,例如 2001:0db8:85a3:0000:0000:8a2e:0370:7334。IPv6 提供了巨大的地址空间,可以满足未来互联网发展的需求。
公网 IP 和 内网 IP
公网 IP
公网 IP 是可以直接在互联网上访问的 IP 地址。每个公网 IP 地址在全球范围内都是唯一的。通常,企业、机构和互联网服务提供商(ISP)会拥有公网 IP 地址。
内网 IP
内网 IP 是用于局域网内部通信的 IP 地址。内网 IP 地址在局域网内部是唯一的,但在不同的局域网中可以重复使用。常见的内网 IP 地址段有 10.0.0.0 - 10.255.255.255、172.16.0.0 - 172.31.255.255 和 192.168.0.0 - 192.168.255.255。
查看本机 IP 地址
Windows 系统
在 Windows 系统中,可以通过以下步骤查看本机 IP 地址:
- 打开命令提示符(CMD)。
- 在命令提示符中输入
ipconfig命令,按下回车键。 - 在输出结果中,可以找到本机的 IP 地址信息。
Linux 系统
在 Linux 系统中,可以通过以下命令查看本机 IP 地址:
ifconfig
macOS 系统
在 macOS 系统中,可以通过以下步骤查看本机 IP 地址:
- 打开 “系统偏好设置”。
- 点击 “网络”。
- 在左侧列表中选择当前连接的网络,右侧会显示本机的 IP 地址信息。
查看是否与对方互通
可以使用 ping 命令来测试是否与对方设备互通。在命令提示符或终端中输入以下命令:
ping 对方 IP 地址
如果能够收到对方设备的响应,表示与对方设备互通;如果无法收到响应,则可能存在网络连接问题。
本机 IP
本机 IP 是指当前设备在网络中的 IP 地址。在局域网中,本机 IP 通常是内网 IP 地址;如果设备直接连接到互联网,则本机 IP 是公网 IP 地址。
TCP 协议特点
TCP(传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层协议。它具有以下特点:
面向连接
在进行数据传输之前,TCP 会先建立连接,确保双方设备都处于可用状态。连接建立后,双方可以进行数据传输,传输完成后,再关闭连接。
可靠传输
TCP 通过确认机制、重传机制和滑动窗口机制等保证数据的可靠传输。如果发送方发送的数据没有收到接收方的确认信息,发送方会重新发送该数据。
字节流传输
TCP 将应用层的数据看作是无结构的字节流进行传输,接收方需要根据应用层的协议来解析这些字节流。
拥塞控制
TCP 具有拥塞控制机制,当网络出现拥塞时,TCP 会自动调整发送数据的速率,以避免网络拥塞进一步恶化。
UDP 通信
UDP(用户数据报协议)是一种无连接的、不可靠的传输层协议。与 TCP 不同,UDP 在进行数据传输之前不需要建立连接,也不保证数据的可靠传输。UDP 的特点是传输速度快、开销小,适用于对实时性要求较高、对数据准确性要求相对较低的应用场景,例如视频直播、音频通话等。
以下是一个简单的 Java UDP 通信示例:
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;// UDP 发送端
class UDPSender {public static void main(String[] args) throws IOException {// 创建 DatagramSocket 对象DatagramSocket socket = new DatagramSocket();// 要发送的数据String message = "Hello, UDP!";byte[] sendData = message.getBytes();// 目标地址和端口InetAddress address = InetAddress.getByName("localhost");int port = 8888;// 创建 DatagramPacket 对象DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, address, port);// 发送数据socket.send(sendPacket);// 关闭套接字socket.close();}
}// UDP 接收端
class UDPReceiver {public static void main(String[] args) throws IOException {// 创建 DatagramSocket 对象,并指定端口号DatagramSocket socket = new DatagramSocket(8888);// 创建接收数据的缓冲区byte[] receiveData = new byte[1024];// 创建 DatagramPacket 对象DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);// 接收数据socket.receive(receivePacket);// 解析接收到的数据String message = new String(receivePacket.getData(), 0, receivePacket.getLength());System.out.println("Received: " + message);// 关闭套接字socket.close();}
}
TCP 通信
TCP 通信是一种面向连接的通信方式,需要先建立连接,再进行数据传输,最后关闭连接。以下是一个简单的 Java TCP 通信示例:
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;// TCP 服务器端
class TCPServer {public static void main(String[] args) {try (ServerSocket serverSocket = new ServerSocket(9999)) {System.out.println("Server is listening on port 9999...");// 等待客户端连接Socket socket = serverSocket.accept();System.out.println("Client connected: " + socket.getInetAddress());// 获取输入流BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));// 获取输出流PrintWriter out = new PrintWriter(socket.getOutputStream(), true);// 读取客户端发送的数据String inputLine;while ((inputLine = in.readLine()) != null) {System.out.println("Received from client: " + inputLine);// 向客户端发送响应out.println("Server received: " + inputLine);}// 关闭连接socket.close();} catch (IOException e) {e.printStackTrace();}}
}// TCP 客户端
class TCPClient {public static void main(String[] args) {try (Socket socket = new Socket("localhost", 9999);PrintWriter out = new PrintWriter(socket.getOutputStream(), true);BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in))) {String userInput;while ((userInput = stdIn.readLine()) != null) {// 向服务器发送数据out.println(userInput);// 读取服务器的响应String response = in.readLine();System.out.println("Received from server: " + response);}} catch (IOException e) {e.printStackTrace();}}
}
综合案例
假设我们要实现一个简单的文件传输系统,客户端将本地文件发送给服务器,服务器接收文件并保存到本地。以下是一个基于 TCP 协议的文件传输系统的示例代码:
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;// 文件传输服务器端
class FileTransferServer {public static void main(String[] args) {try (ServerSocket serverSocket = new ServerSocket(12345)) {System.out.println("Server is listening on port 12345...");// 等待客户端连接Socket socket = serverSocket.accept();System.out.println("Client connected: " + socket.getInetAddress());// 获取输入流InputStream in = socket.getInputStream();// 创建文件输出流FileOutputStream fos = new FileOutputStream("received_file.txt");byte[] buffer = new byte[4096];int bytesRead;while ((bytesRead = in.read(buffer)) != -1) {fos.write(buffer, 0, bytesRead);}// 关闭流和连接fos.close();in.close();socket.close();System.out.println("File received successfully.");} catch (IOException e) {e.printStackTrace();}}
}// 文件传输客户端
class FileTransferClient {public static void main(String[] args) {try (Socket socket = new Socket("localhost", 12345);FileInputStream fis = new FileInputStream("test_file.txt");OutputStream out = socket.getOutputStream()) {byte[] buffer = new byte[4096];int bytesRead;while ((bytesRead = fis.read(buffer)) != -1) {out.write(buffer, 0, bytesRead);}// 关闭流和连接fis.close();out.close();socket.close();System.out.println("File sent successfully.");} catch (IOException e) {e.printStackTrace();}}
}
总结
通过今天的学习,我们对 Java 网络编程有了更深入的了解。掌握了基本的通信架构、网络编程三要素、IP 地址、TCP 协议和 UDP 通信等基础知识,并通过实际的代码示例加深了对这些知识的理解和应用。网络编程是 Java 开发中非常重要的一部分,在实际项目中有着广泛的应用,我们需要不断学习和实践,才能更好地掌握这门技术。
相关文章:
Java进阶之旅-day05:网络编程
引言 在当今数字化的时代,网络编程在软件开发中扮演着至关重要的角色。Java 作为一门广泛应用的编程语言,提供了强大的网络编程能力。今天,我们深入学习了 Java 网络编程的基础知识,包括基本的通信架构、网络编程三要素、IP 地址、…...
Vue 3 的响应式原理
Vue 3 的响应式原理可以比喻为“智能监控系统”:当数据变化时,它能自动追踪依赖关系并触发更新。以下是通俗解释和核心机制: 一、核心原理:Proxy 代理 Vue 3 的响应式系统基于 JavaScript 的 Proxy 对象实现(Vue 2 使…...
Python解决“组成字符串ku的最大次数”问题
Python解决“组成字符串ku的最大次数”问题 问题描述测试样例解题思路代码 问题描述 给定一个字符串 s,该字符串中只包含英文大小写字母。你需要计算从字符串中最多能组成多少个字符串 “ku”。每次可以随机从字符串中选一个字符,并且选中的字符不能再使…...
【JS】使用滑动窗口得到无重复字符的最长子串
题目 思路 本题采用滑动窗口思想,定义左右指针作为滑动窗口的边界,使用Set数据结构处理重复字符,需要注意的是:每次遍历时采用Math.max方法实时更新最长子串的长度;当左指针移动时,set要删除对应字符。 步…...
libreoffice-help-common` 的版本(`24.8.5`)与官方源要求的版本(`24.2.7`)不一致
出现此错误的原因主要是软件包依赖冲突,具体分析如下: ### 主要原因 1. **软件源版本不匹配(国内和官方服务器版本有差距) 系统中可能启用了第三方软件源(如 PPA 或 backports 源),导致 lib…...
2025-04-05 吴恩达机器学习4——逻辑回归(1):基础入门
文章目录 1 分类问题1.1 介绍1.2 线性回归与分类1.2 逻辑回归 2 逻辑回归2.1 介绍2.2 Sigmoid 函数2.3 逻辑回归模型 3 决策边界3.1 概念3.2 线性决策边界3.3 非线性决策边界 4 代价函数4.1 不使用平方误差4.2 损失函数4.3 整体代价函数 5 梯度下降5.1 参数更新5.2 逻辑回归 vs…...
P1125 [NOIP 2008 提高组] 笨小猴
#include<bits/stdc.h> using namespace std; int a[300],ma,mi105;//数组用来记录每个字符出现的次数,将mi初始为一个比较大的值 bool is_prime(int x){if(x0||x1)return false;for(int i2;i*i<x;i){if(x%i0)return false;}return true; }//判断是否为质…...
Linux systemd 服务全面详解
一、systemd 是什么? systemd 是 Linux 系统的现代初始化系统(init)和服务管理器,替代传统的 SysVinit 和 Upstart。它不仅是系统启动的“总指挥”,还统一管理服务、日志、设备挂载、定时任务等。 核心作用 服务管理…...
SortedSet结构之用户积分实时榜单实战
Redis 中的SortedSet结构非常适合用于实现实时榜单的场景,它根据成员的分数自动进行排序,支持高效的添加、更新和查询操作。 SortedSet实时榜单的一些典型应用场景: 游戏中的玩家排行榜:在多人在线游戏中,使用 Sorte…...
C++_类和对象(中)
【本节目标】 类的6个默认成员函数构造函数析构函数拷贝构造函数赋值运算符重载const成员函数取地址及const取地址操作符重载 1. 类的6个默认成员函数 如果一个类中什么成员都没有,简称为空类。 空类中真的什么都没有吗?并不是,任何类在什…...
#SVA语法滴水穿石# (007)关于 $past 的用法
今天,我们要学习比较重要的一个关键字。$past 的用法,今天系统学习。 1. $past 函数的核心作用 $past 用于 获取某个信号在过去指定时钟周期前的值,通常用于检查历史状态是否符合预期。 其语法如下: $past(signal, [num_cycles], [gating_condition], [clock], [reset])…...
学习笔记—C++—入门基础()
目录 C介绍 参考文档 C第一个程序 命名空间namespace namespace的价值 namespace的定义 namespace使用 指定命名空间访问 using将命名空间中某个成员展开 展开命名空间中全部成员 输入和输出 缺省参数 函数重载 引用 引用的概念 应用 const引用 指针和引用的关…...
kotlin函数类型
一 函数类型定义 1 定义 函数类型就是 (Int, Int) -> Int 函数类型其实就是将函数的 “参数类型” 和 “返回值类型” 抽象出来 2 示例 : (Int, Int) -> Int 表示接收两个 Int 参数并返回 Int 的函数类型; (String) -> Unit 表示接收 Strin…...
大数据Spark(五十七):Spark运行架构与MapReduce区别
文章目录 Spark运行架构与MapReduce区别 一、Spark运行架构 二、Spark与MapReduce区别 Spark运行架构与MapReduce区别 一、Spark运行架构 Master:Spark集群中资源管理主节点,负责管理Worker节点。Worker:Spark集群中资源管理的从节点,负责任务的运行…...
虚拟Ashx页面,在WEB.CONFIG中不添加handlers如何运行
https://localhost:44311/webapi.ashx 虚拟ASHX页面,在WEB.CONFIG中添加handlers,如何不添加节点,直接运行?把页面直接保存ASHX名称?现在是.VB 如果你不想通过在 web.config 里添加 handlers 节点来配置处理程序,而是直接让 .as…...
道路裂缝数据集CrackForest-156-labelme
来源于开源的数据集 https://github.com/cuilimeng/CrackForest-dataset 进行整理修改而成。 文章目录 1. 介绍2. 应用场景3. 相关工具4. 下载地址 1. 介绍 在现代城市管理中,道路状况的监测与维护是确保交通安全和城市基础设施健康的重要环节。 CrackForest是一个…...
HTML 表单:构建交互式网页的关键元素
HTML 表单:构建交互式网页的关键元素 引言 HTML表单是构建交互式网页的核心组件之一,它允许用户与网站进行交互,提交信息、填写问卷或进行其他操作。本文将深入探讨HTML表单的基础知识、常用元素、表单验证以及如何优化表单设计,以提高用户体验和网站的可访问性。 HTML表…...
Java进阶-day06:反射、注解与动态代理深度解析
目录 一、反射机制:Java的自我认知能力 1.1 认识反射 1.2 获取Class对象 1.3 获取类的成分 二、注解:Java的元数据机制 2.1 注解概述 2.2 元注解 2.3 注解解析 2.4 注解的实际应用 三、动态代理:灵活的间接访问机制 3.1 为什么需要…...
Redis数据结构之Hash
目录 1.概述2.常见操作2.1 H(M)SET/H(M)GET2.2 HGETALL2.3 HDEL2.4 HLEN2.5 HEXISTS2.6 HKEYS/HVALS2.7 HINCRBY2.8 HSETNX 3.总结 1.概述 Hash是一个String类型的field(字段)和value(值)的映射表,而且value是一个键值对集合,类似Map<String, Map<…...
故障矩阵像素照片效果ps标题文本特效滤镜样机 Glitched Arcade Text Logo Effect
有时,视觉效果比文字本身更能讲述故事,因此请确保您已竭尽全力提供令人敬畏的展示。品牌标识或演示元素,该资产可以处理您的项目所涉及的任何内容。由于智能对象图层,此文本效果将为获得理想的结果铺平道路。这些允许您在指定的图…...
[创业之路-352]:从创业和公司经营的角度看:分析美国的三大财务报表
一、美国政府的财务报表 如果把美国政府看成一个公司,从三大财务报表上看,美国政府资产雄厚,但利润表年年亏损,现金流量表年年为负,现金流持续吃紧,面临现金流断裂导致公司倒闭的风险。 马斯克在降低公司各…...
【学Rust写CAD】27 双线性插值函数(bilinear_interpolation.rs)
源码 use super::constant::BILINEAR_INTERPOLATION_BITS; // Inspired by Filter_32_opaque from Skia. fn bilinear_interpolation(tl: u32,tr: u32,bl: u32,br: u32,mut distx: u32,mut disty: u32, ) -> u32 {let distxy;let distxiy;let distixy;let distixiy;let mut…...
vs环境中编译osg以及osgQt
1、下载 OpenSceneGraph 获取源代码 您可以通过以下方式获取 OSG 源代码: 官网下载:https://github.com/openscenegraph/OpenSceneGraph/releases 使用 git 克隆: git clone https://github.com/openscenegraph/OpenSceneGraph.git 2、下载必要的第三方依赖库 依赖库 ht…...
【教学类-102-02】自制剪纸图案(留白边、沿线剪)02——Python+PS自动化添加虚线边框
背景需求: 01版本实现了对透明背景png图案边界线的扩展,黑线实线描边 【教学类-102-01】自制剪纸图案(留白边、沿线剪)01-CSDN博客文章浏览阅读974次,点赞15次,收藏7次。【教学类-102-01】自制剪纸图案(留白边、沿线剪)01https://blog.csdn.net/reasonsummer/article…...
基于 Netty 框架的 Java TCP 服务器端实现,用于启动一个 TCP 服务器来处理客户端的连接和数据传输
代码: package com.example.tpson_tcp;import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelOption; import io.netty.channel.EventLoopGroup; imp…...
fbx bip互转 测试OK
目录 fbx bip互转 3dmax插件fbx转bip: 测试可以转: MotionBuilder fbx转bip fbx bip互转 3dmax插件fbx转bip: 测试可以转: 不用插件!!无脑把Mxiamo转bip骨骼动画 - CG软件插件脚本交流 - Powered by Discuz!...
iptables只允许指定网段的ip访问某端口配置
yum install -y iptables-services #安装 systemctl restart iptables.service #重启防火墙使配置生效 systemctl enable iptables.service #设置防火墙开机启动 systemctl disable iptables.service #禁止防火墙开机启动 iptables -F 清除所有链的规则。 关闭所有访问端口 …...
OFP--2018
文章目录 AbstractIntroductionRelated Work2D object detection3D object detection from LiDAR3D object detection from imagesIntegral images 3D Object Detection ArchitectureFeature extractionOrthographic feature transformFast average pooling with integral imag…...
libevent DNS开发
一、DNS功能 Libevent的DNS功能提供异步解析与服务器搭建能力,其核心设计分为阻塞式解析与事件驱动异步解析两套机制。 阻塞式解析(同步) 功能定位 通过evutil_getaddrinfo()提供可移植的阻塞式域名解析,兼容无标准getaddrinfo()接口的系统(如旧版…...
CentOS-查询实时报错日志-查询前1天业务报错gz压缩日志
最新版本更新 https://code.jiangjiesheng.cn/article/364?fromcsdn 推荐 《高并发 & 微服务 & 性能调优实战案例100讲 源码下载》 1. 查询实时报错日志 物理路径(带*的放在靠后,或者不用*) cd /home/logs/java-gz-log-dir &am…...
