当前位置: 首页 > news >正文

13Java 网络编程

✨博客主页: https://blog.csdn.net/m0_63815035?type=blog

💗《博客内容》:大数据、AI开发、Java、测试开发、Python、Android、Go、Node、Android前端小程序等相关领域知识
📢博客专栏:https://blog.csdn.net/m0_63815035/category_11954877.html
📢欢迎点赞 👍 收藏 ⭐留言 📝
📢本文为学习笔记资料,如有侵权,请联系我删除,疏漏之处还请指正🙉
📢大厦之成,非一木之材也;大海之阔,非一流之归也✨


目录

    • 一、计算机网络基础
      • 1.1 什么是计算机网络
      • 1.2 网络通信协议
      • 1.3 网络分层模型
        • OSI 七层模型(理论模型)
        • TCP/IP 四层模型(实际应用)
      • 1.4 数据封装与拆封
    • 二、IP 地址与端口
      • 2.1 IP 地址
      • 2.2 端口
      • 2.3 InetAddress 类(Java 中表示 IP 地址)
      • 2.4 InetSocketAddress 类(IP + 端口)
    • 三、URL 与网络资源访问
      • 3.1 URL 简介
      • 3.2 URL 类(java.net.URL)
      • 3.3 网络爬虫雏形(下载网页)
    • 四、传输层协议:TCP 与 UDP
    • 五、UDP 编程(DatagramSocket + DatagramPacket)
      • 5.1 DatagramSocket
      • 5.2 DatagramPacket
      • 5.3 UDP 服务端示例
      • 5.4 UDP 客户端示例
    • 六、TCP 编程(ServerSocket + Socket)
      • 6.1 ServerSocket(服务端)
      • 6.2 Socket(客户端/服务端通信端点)
      • 6.3 TCP 服务端示例(接收客户端消息并回复)
      • 6.4 TCP 客户端示例
      • 6.5 多线程 TCP 服务端(支持多个客户端同时连接)
    • 七、TCP 三次握手与四次挥手(简单理解)
    • 八、常见问题与最佳实践
      • 8.1 常见异常及处理
      • 8.2 性能与资源管理
      • 8.3 数据编码
      • 8.4 协议选择
    • 九、结尾

网络编程是 Java 高级开发的重要部分,用于实现跨主机的数据交换。本文从网络基础概念讲起,详细介绍 InetAddress、URL、UDP 和 TCP 编程,并提供完整的服务端/客户端代码示例,覆盖常见注意事项和最佳实践。


一、计算机网络基础

1.1 什么是计算机网络

计算机网络是将分布在不同地理区域的计算机与外部设备通过通信线路互连,形成一个规模大、功能强的网络系统,使众多计算机可以方便地传递信息,共享硬件、软件、数据等资源。

主要功能

  • 资源共享
  • 信息传输与集中处理
  • 均衡负荷与分布处理

1.2 网络通信协议

通信协议是计算机网络中实现通信必须遵守的规则和约定,包括:速率、传输代码、代码结构、传输控制步骤、出错控制等。

协议三要素:

  • 语义:做什么(如控制信息、差错处理)
  • 语法:怎么做(数据结构、格式)
  • 时序:做的顺序(速度匹配、排序)

1.3 网络分层模型

OSI 七层模型(理论模型)
层级名称作用
7应用层提供用户接口(HTTP、FTP、SMTP)
6表示层数据转换、加密、压缩
5会话层建立、管理、终止会话
4传输层端到端可靠传输(TCP、UDP)
3网络层路由选择、IP 地址
2数据链路层帧传输、差错控制
1物理层比特流传输、硬件接口

TCP/IP 四层模型(实际应用)
层级名称协议示例
4应用层HTTP、FTP、DNS、SMTP
3传输层TCP、UDP
2网际层IP、ICMP、ARP
1网络接口层以太网、WiFi

1.4 数据封装与拆封

  • 封装:发送数据时,从应用层向下传递,每层加上本层的头部(可能尾部),形成数据包。

  • 拆封:接收数据时,从物理层向上传递,每层去掉本层的头部,还原原始数据。

理解封装与拆封,有助于理解网络编程中“流”的概念。


二、IP 地址与端口

2.1 IP 地址

IP 地址用于唯一标识网络中的计算机(或网络设备)。IPv4 地址为 32 位整数,通常用点分十进制表示(如192.168.1.1)。IPv6 为 128 位,用冒号十六进制表示。

特殊 IP

  • 127.0.0.1:本地回环地址,代表本机。
  • localhost:本地主机域名,默认映射到127.0.0.1

2.2 端口

端口是虚拟概念,用于区分同一主机上的不同网络应用程序。端口号范围0~65535

  • 0~1023:系统保留端口(如 HTTP 80,FTP 21,SSH 22)
  • 1024~49151:注册端口(用户程序可使用)
  • 49152~65535:动态/私有端口

注意:编写程序时,建议使用 1024 以上的端口,避免冲突。

2.3 InetAddress 类(Java 中表示 IP 地址)

java.net.InetAddress用于封装 IP 地址和域名,不包含端口信息。该类没有公共构造方法,通过静态方法获取实例。

常用静态方法

方法说明
InetAddress.getLocalHost()获取本机 InetAddress 对象
InetAddress.getByName(String host)根据域名或 IP 字符串获取
InetAddress.getAllByName(String host)获取域名对应的所有 IP(适用于多 IP 主机)

实例方法

方法说明
String getHostAddress()返回 IP 地址字符串
String getHostName()返回域名(若无法解析则返回 IP)
boolean isReachable(int timeout)测试是否可达(ICMP ping)

示例

importjava.net.InetAddress;publicclassInetAddressDemo{publicstaticvoidmain(String[]args)throwsException{// 本机InetAddresslocal=InetAddress.getLocalHost();System.out.println("本机IP:"+local.getHostAddress());System.out.println("本机名:"+local.getHostName());// 根据域名获取InetAddressbaidu=InetAddress.getByName("www.baidu.com");System.out.println("百度IP:"+baidu.getHostAddress());System.out.println("百度域名:"+baidu.getHostName());// 根据 IP 获取(可能无法反向解析域名)InetAddressbyIp=InetAddress.getByName("8.8.8.8");System.out.println("8.8.8.8 主机名:"+byIp.getHostName());// 可能仍返回 IP}}

2.4 InetSocketAddress 类(IP + 端口)

java.net.InetSocketAddress包含 IP 地址(或主机名)和端口号,常用于 Socket 通信中指定远程端点。

构造方法

  • InetSocketAddress(String hostname, int port)
  • InetSocketAddress(InetAddress addr, int port)
  • InetSocketAddress(int port):创建只包含端口的通配地址(用于服务器)

常用方法

  • InetAddress getAddress()
  • int getPort()
  • String getHostName()
InetSocketAddressendpoint=newInetSocketAddress("localhost",8888);System.out.println("主机名:"+endpoint.getHostName());System.out.println("端口:"+endpoint.getPort());System.out.println("IP:"+endpoint.getAddress().getHostAddress());

三、URL 与网络资源访问

3.1 URL 简介

URL(Uniform Resource Locator)统一资源定位符,用于标识互联网上资源的位置。格式:

protocol://userInfo@host:port/path?query#fragment
  • protocol:协议(http, https, ftp, file 等)
  • host:域名或 IP
  • port:端口(可省略,使用协议默认端口)
  • path:资源路径
  • query:查询参数(如?id=1&name=xx
  • fragment:锚点(定位到页面内某位置)

3.2 URL 类(java.net.URL)

构造方法

  • URL(String spec):完整 URL 字符串
  • URL(String protocol, String host, int port, String file)
  • URL(URL context, String spec):相对路径构造

常用方法

  • String getProtocol():获取协议名
  • String getHost():获取主机名
  • int getPort():获取端口(若未指定返回 -1)
  • String getPath():获取路径
  • String getQuery():获取查询参数
  • InputStream openStream():打开到此 URL 的连接并返回输入流(用于读取资源)

3.3 网络爬虫雏形(下载网页)

importjava.io.*;importjava.net.URL;publicclassURLDownload{publicstaticvoidmain(String[]args)throwsException{URLurl=newURL("https://www.baidu.com");// 使用 try-with-resources 自动关闭流try(InputStreamis=url.openStream();BufferedReaderreader=newBufferedReader(newInputStreamReader(is,"UTF-8"));BufferedWriterwriter=newBufferedWriter(newFileWriter("baidu.html"))){Stringline;while((line=reader.readLine())!=null){writer.write(line);writer.newLine();}}System.out.println("下载完成");}}

注意:实际网络爬虫需要考虑:User-Agent 伪装、请求延迟、异常处理、编码识别等,本示例仅供学习原理。


四、传输层协议:TCP 与 UDP

特性TCPUDP
连接性面向连接(三次握手)无连接
可靠性可靠、确认重传不可靠,可能丢包
有序性保证顺序不保证顺序
流量控制
开销大(头部 20 字节)小(头部 8 字节)
速度
应用场景HTTP、FTP、SSH、数据库视频直播、DNS、VoIP

比喻:TCP 像打电话(先拨号建立连接,再通话,挂断),UDP 像寄信(不管对方是否收到,直接发送)。


五、UDP 编程(DatagramSocket + DatagramPacket)

UDP 使用DatagramSocket发送/接收DatagramPacket数据报。

5.1 DatagramSocket

  • 用于发送或接收数据报的套接字。
  • 构造方法:
    • DatagramSocket():系统随机分配本地端口(客户端常用)
    • DatagramSocket(int port):绑定到指定端口(服务端常用)
    • DatagramSocket(int port, InetAddress bindAddr):绑定到特定网卡
  • 常用方法:
    • void send(DatagramPacket p)
    • void receive(DatagramPacket p)(阻塞)
    • void close()

5.2 DatagramPacket

  • 数据报容器,包含数据、长度、目标地址和端口。
  • 构造方法(发送用):
    • DatagramPacket(byte[] buf, int length, InetAddress address, int port)
    • DatagramPacket(byte[] buf, int length, SocketAddress address)
  • 构造方法(接收用):
    • DatagramPacket(byte[] buf, int length)
  • 常用方法:
    • byte[] getData()
    • int getLength()
    • InetAddress getAddress()
    • int getPort()

5.3 UDP 服务端示例

importjava.net.DatagramPacket;importjava.net.DatagramSocket;publicclassUDPServer{publicstaticvoidmain(String[]args)throwsException{// 1. 创建服务端 DatagramSocket,监听端口 8888try(DatagramSocketds=newDatagramSocket(8888)){byte[]buf=newbyte[1024];DatagramPacketdp=newDatagramPacket(buf,buf.length);System.out.println("UDP 服务端已启动,等待数据...");ds.receive(dp);// 阻塞,直到收到数据报Stringreceived=newString(dp.getData(),0,dp.getLength());System.out.println("收到客户端消息:"+received);System.out.println("客户端地址:"+dp.getAddress().getHostAddress()+":"+dp.getPort());}}}

5.4 UDP 客户端示例

importjava.net.DatagramPacket;importjava.net.DatagramSocket;importjava.net.InetSocketAddress;publicclassUDPClient{publicstaticvoidmain(String[]args)throwsException{// 1. 创建客户端 DatagramSocket(系统自动分配端口)try(DatagramSocketds=newDatagramSocket()){Stringmsg="Hello UDP Server";byte[]buf=msg.getBytes("UTF-8");// 封装数据包,指定目标地址和端口DatagramPacketdp=newDatagramPacket(buf,buf.length,newInetSocketAddress("localhost",8888));ds.send(dp);System.out.println("数据已发送");}}}

注意:UDP 是不可靠的,如果服务端未启动,客户端发送不会报错,但数据会丢失。如果需要确认,可以设计应用层确认机制。


六、TCP 编程(ServerSocket + Socket)

TCP 通信需要服务端ServerSocket监听端口,客户端Socket发起连接,建立后通过Socket的输入输出流进行双向通信。

6.1 ServerSocket(服务端)

  • 构造方法:
    • ServerSocket(int port):绑定到端口,默认最大等待队列长度 50
    • ServerSocket(int port, int backlog):指定队列长度
    • ServerSocket(int port, int backlog, InetAddress bindAddr):绑定到指定网卡
  • 常用方法:
    • Socket accept():阻塞等待客户端连接,返回Socket对象
    • void close()

6.2 Socket(客户端/服务端通信端点)

  • 客户端构造方法:
    • Socket(String host, int port):连接指定主机和端口
    • Socket(InetAddress address, int port)
  • 服务端通过accept()返回的Socket
  • 常用方法:
    • InputStream getInputStream()
    • OutputStream getOutputStream()
    • void close()
    • InetAddress getInetAddress()
    • int getPort()

6.3 TCP 服务端示例(接收客户端消息并回复)

importjava.io.*;importjava.net.ServerSocket;importjava.net.Socket;publicclassTCPServer{publicstaticvoidmain(String[]args){try(ServerSocketserver=newServerSocket(8888)){System.out.println("TCP 服务端已启动,等待连接...");Socketsocket=server.accept();// 阻塞System.out.println("客户端已连接:"+socket.getInetAddress().getHostAddress());// 接收客户端数据BufferedReaderreader=newBufferedReader(newInputStreamReader(socket.getInputStream()));Stringline=reader.readLine();System.out.println("收到客户端消息:"+line);// 向客户端发送响应BufferedWriterwriter=newBufferedWriter(newOutputStreamWriter(socket.getOutputStream()));writer.write("已收到消息:"+line);writer.newLine();writer.flush();socket.close();}catch(IOExceptione){e.printStackTrace();}}}

6.4 TCP 客户端示例

importjava.io.*;importjava.net.Socket;publicclassTCPClient{publicstaticvoidmain(String[]args){try(Socketsocket=newSocket("localhost",8888)){// 发送数据BufferedWriterwriter=newBufferedWriter(newOutputStreamWriter(socket.getOutputStream()));writer.write("Hello TCP Server");writer.newLine();writer.flush();// 接收响应BufferedReaderreader=newBufferedReader(newInputStreamReader(socket.getInputStream()));Stringresponse=reader.readLine();System.out.println("服务端响应:"+response);}catch(IOExceptione){e.printStackTrace();}}}

6.5 多线程 TCP 服务端(支持多个客户端同时连接)

实际开发中,服务端需要同时处理多个客户端,应为每个客户端分配独立线程。

publicclassMultiThreadTCPServer{publicstaticvoidmain(String[]args)throwsIOException{ServerSocketserver=newServerSocket(8888);System.out.println("服务端启动,等待客户端...");while(true){Socketsocket=server.accept();// 每个客户端交给一个线程处理newThread(newClientHandler(socket)).start();}}staticclassClientHandlerimplementsRunnable{privateSocketsocket;ClientHandler(Sockets){socket=s;}@Overridepublicvoidrun(){try(socket){BufferedReaderreader=newBufferedReader(newInputStreamReader(socket.getInputStream()));BufferedWriterwriter=newBufferedWriter(newOutputStreamWriter(socket.getOutputStream()));Stringline;while((line=reader.readLine())!=null){System.out.println("收到:"+line);writer.write("Echo: "+line);writer.newLine();writer.flush();}}catch(IOExceptione){e.printStackTrace();}}}}

注意:实际项目中常使用线程池管理线程,避免无限制创建线程导致资源耗尽。


七、TCP 三次握手与四次挥手(简单理解)

  • 三次握手(建立连接):

    1. Client → Server:SYN(请求连接)
    2. Server → Client:SYN+ACK(同意连接)
    3. Client → Server:ACK(确认连接建立)
  • 四次挥手(断开连接):

    1. Client → Server:FIN(请求断开)
    2. Server → Client:ACK(确认收到)
    3. Server → Client:FIN(关闭服务端到客户端连接)
    4. Client → Server:ACK(确认关闭)

八、常见问题与最佳实践

8.1 常见异常及处理

异常可能原因解决方法
BindException端口已被占用更换端口,或关闭占用进程
ConnectException连接被拒绝(服务端未启动)确保服务端已运行
SocketTimeoutException读写超时设置setSoTimeout或检查网络
SocketException: Socket closed在关闭后读写检查代码逻辑,避免使用已关闭的流
UnknownHostException主机名无法解析检查 DNS 或 IP 是否正确

8.2 性能与资源管理

  • 使用try-with-resources自动关闭 Socket 和流(Java 7+)。
  • 服务端使用线程池处理并发请求,避免new Thread()无限制。
  • 设置合理的SO_TIMEOUT防止 accept 或 read 无限阻塞。
  • 对于长连接,建议设置SO_KEEPALIVE或应用层心跳。

8.3 数据编码

  • 网络传输建议统一使用UTF-8编码,避免乱码。
  • 使用InputStreamReader/OutputStreamWriter并指定字符集。

8.4 协议选择

  • 需要可靠传输、顺序保证、数据完整性 →TCP
  • 实时性要求高、允许少量丢包 →UDP

九、结尾

核心类作用常用方法
InetAddress封装 IP/域名getByName,getHostAddress
InetSocketAddressIP + 端口getAddress,getPort
URL资源定位openStream
DatagramSocketUDP 套接字send,receive,close
DatagramPacketUDP 数据报构造、getData
ServerSocketTCP 服务端监听accept
SocketTCP 双向通信getInputStream,getOutputStream

掌握网络编程需要理解 TCP/UDP 协议区别,熟悉 Java 提供的 Socket API,并能处理多线程、资源关闭、异常等实际问题。建议多动手编写聊天室、文件传输等小项目加深理解。

今天这篇文章就到这里了,大厦之成,非一木之材也;大海之阔,非一流之归也。感谢大家观看本文

http://www.jsqmd.com/news/993791/

相关文章:

  • 2026检测认证行业气路系统优质厂家推荐 - 资讯速览
  • SpringBoot项目里调用老旧C# WebService接口,我是怎么一步步搞定XML解析和JSON转换的
  • 组织能力地图的设计方法
  • 哈尔滨收的顶手表回收,连锁老店资质齐全交易更安心 - 奢侈品回收测评
  • 3步精通猫抓神器:浏览器资源嗅探终极使用指南
  • 零基础学STK中文实操包:8本PDF教材+Word分步指南+配套示例与开发文档
  • AGI 时代的经济结构演进:关系型部门价值、资本扩张逻辑与转型路径研判
  • 告别水准仪!用Sentinel-1数据和时序InSAR,我如何在家监测城市地面沉降(附完整Python代码)
  • 深度学习木马攻击原理与防御技术详解
  • DeepSeek V4 Pro + Flash 分工编程:成本骤降 60%+ 的混合模型工作流
  • 如何彻底解决显卡驱动问题:专业免费工具的终极指南
  • 2026 湛江黄金回收价位参考 全域实体门店综合测评 - 靖昱黄金回收
  • 2026 宜昌防水补漏服务商口碑测评榜单|全屋渗漏维修机构优选指南 - 宅安选房屋修缮
  • FLUX.1-dev FP8模型:如何在24GB以下显卡实现专业级AI图像生成
  • 终极AI视频抠像指南:如何用MatAnyone实现专业级人物分离与背景替换
  • Demucs 6秒音频分离:终极快速免费音乐源分离工具
  • 价差明显!对比广州数十家回收点 教你选出高性价比门店 - 开心测评
  • 深入解析OL2381射频收发器:工作模式切换与PLL启动流程
  • IINA:macOS终极视频播放器完整指南 - 免费开源的高性能播放解决方案
  • GR-RL具身强化学习框架 本文详细列出了深度学习优化器、学习率调度、特征处理、归一化层、激活函数、时序注意力、强化学习、传感器融合、机械臂控制等60项AI系统底层参数配置。涵盖AdamW优化器(β1
  • 石家庄黄金回收怎么选?禹竞名奢汇凭国检认证稳居行业红榜头部 - 名奢变现站
  • 暗黑破坏神2存档编辑器:可视化编辑工具让游戏修改变得简单高效
  • 厦门格拉芙首饰回收行情解析!本地GRAFF顶奢珠宝无套路出手指南 - 开心测评
  • 大连手表去哪里卖最划算?2026名表回收行情+6家靠谱门店全攻略 - 奢侈品回收评测
  • 2026上海APP开发公司深度评测:技术实力、交付能力与行业口碑全景解析 - IT老炮老刘
  • Obsidian微信读书插件终极指南:3步打造个人知识图书馆
  • UVa 459 Graph Connectivity
  • 手把手教你给RT-Thread设备加个“黑匣子”:用W25Q128和ulog实现日志持久化存储
  • PyTorch开放集识别实战工具包:支持MNIST/CIFAR/ImageNet,集成OpenMax、Center-Loss与VAE建模
  • C#版NFC开发套件:支持MIFARE Classic读写与Crypto1加解密的即用工程