Java 网络编程入门:TCP/UDP 通信与 URL 类详解
学习 Java 网络编程,需先理解底层协议与 API。本文将带你从零搭建 TCP 连接,实现文件传输,掌握 UDP 无连接通信,并学会使用 URL 类解析网络地址,提供从原理到代码的完整入门指导。
网络基础架构
在进行网络编程之前,理解计算机网络的分层模型至关重要。Java 主要工作在传输层和网络层,屏蔽了底层的物理传输细节。

TCP 协议与 Socket 编程
TCP(Transmission Control Protocol)是面向连接的、可靠的、基于字节流的运输层通信协议。在 Java 中,我们主要通过 java.net.Socket 和 java.net.ServerSocket 类来实现 TCP 通信。
第1步:建立简单的文本交互
目的:实现客户端向服务端发送简单文本,服务端接收并打印到控制台。
关键类:InetAddress, Socket, ServerSocket, InputStream, OutputStream.
public class TCPTest1 {
//客户端
@Test
public void client() {
Socket socket = null;
OutputStream os = null;
try {
//1.创建Socket对象,指明服务器端的ip和端口号
InetAddress inet = InetAddress.getByName("127.0.0.1");
socket = new Socket(inet, 8899);
//2.获取一个输出流,用于输出数据
os = socket.getOutputStream();
//3.写出数据的操作
os.write("你好,我是客户端mm".getBytes());
} catch (IOException e) {
e.printStackTrace();
} finally {
//4.资源的关闭
if(os != null){
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(socket != null){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//服务端
@Test
public void server(){
ServerSocket ss = null;
Socket socket = null;
InputStream is = null;
ByteArrayOutputStream baos = null;
try {
//1.创建服务器的ServerSocket,指明自己的端口号
ss = new ServerSocket(8899);
//2.调用accept()表示接收来自于客户端的socket
socket = ss.accept();
//3.获取输入流
is = socket.getInputStream();
//不建议这样写,可能会有乱码
// byte[] buffer = new byte[1024];
// int len;
// while((len = is.read(buffer)) != -1){
// String str = new String(buffer,0,len);
// System.out.println(str);
// }
//4.读取输入流中的数据
baos = new ByteArrayOutputStream();
byte[] buffer = new byte[5];
int len;
while((len = is.read(buffer)) != -1){
baos.write(buffer,0,len);
}
System.out.println(baos.toString());
} catch (IOException e) {
e.printStackTrace();
} finally {
//5.关闭资源
if(baos != null){
try {
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(is != null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(socket != null){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(ss != null){
try {
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}第2步:实现二进制文件传输
目的:将本地图片文件发送至服务端,服务端接收并保存为本地文件。由于涉及大体积数据,通常使用缓冲字节数组 byte[] 进行分块读写。
public class TCPTest2 {
//这里异常处理的方式应该使用try-catch-finally
@Test
public void client() throws IOException {
Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 9090);
OutputStream os = socket.getOutputStream();
FileInputStream fis = new FileInputStream(new File("beauty.jpg"));
byte[] buffer = new byte[1024];
int len;
while((len = fis.read(buffer)) != -1){
os.write(buffer,0,len);
}
fis.close();
os.close();
socket.close();
}
//这里异常处理的方式应该使用try-catch-finally
@Test
public void server() throws IOException {
ServerSocket ss = new ServerSocket(9090);
Socket socket = ss.accept();
InputStream is = socket.getInputStream();
FileOutputStream fos = new FileOutputStream(new File("beauty1.jpg"));
byte[] buffer = new byte[1024];
int len;
while((len = is.read(buffer)) != -1){
fos.write(buffer,0,len);
}
fos.close();
is.close();
socket.close();
ss.close();
}
}第3步:双向通信与反馈机制
目的:在完成文件上传后,服务端通知客户端接收成功。
注意:上述代码中同时打开双向流时需注意逻辑顺序,通常建议明确区分读/写通道或使用 shutdownOutput() 等高级API控制流状态。以下代码展示了基本的双向收发结构,但存在资源释放隐患(如重复获取输出流),生产环境建议重构。
public class TCPTest3 {
@Test
public void client() throws IOException {
Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 9090);
OutputStream os = socket.getOutputStream();
FileInputStream fis = new FileInputStream(new File("beauty.jpg"));
byte[] buffer = new byte[1024];
int len;
while((len = fis.read(buffer)) != -1){
os.write(buffer,0,len);
}
//服务区端给予客户端反馈
OutputStream os1 = socket.getOutputStream();
os.write("你好,美女,照片我以收到,非常漂亮!".getBytes());
fis.close();
os.close();
socket.close();
os1.close();
}
//这里异常处理的方式应该使用try-catch-finally
@Test
public void server() throws IOException {
ServerSocket ss = new ServerSocket(9090);
Socket socket = ss.accept();
InputStream is = socket.getInputStream();
FileOutputStream fos = new FileOutputStream(new File("beauty2.jpg"));
byte[] buffer = new byte[1024];
int len;
while((len = is.read(buffer)) != -1){
fos.write(buffer,0,len);
}
//接受来自于服务器端的数据,并显示到控制台上
InputStream is1 = socket.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] bufferr = new byte[20];
int len1;
while((len1 = is1.read(buffer)) != -1){
baos.write(buffer,0,len1);
}
System.out.println(baos.toString());
fos.close();
is.close();
socket.close();
ss.close();
baos.close();
}
}
UDP 协议编程
UDP(User Datagram Protocol)是无连接的、不可靠的传输协议。它不需要预先建立连接,直接发送数据包(Datagram)。适用于对实时性要求高、允许少量丢包的场景(如视频会议、直播)。
Java 实现要点:
DatagramSocket:负责发送和接收数据包。DatagramPacket:封装数据包,包含发送的目标地址、端口、数据和长度。
UDP协议的网络编程
public class UDPTest {
@Test
public void sender() throws IOException {
DatagramSocket socket = new DatagramSocket();
String str = "我是UDP方式发送的导弹";
byte[] data = str.getBytes();
InetAddress inet = InetAddress.getLocalHost();
DatagramPacket packet = new DatagramPacket(data,0,data.length,inet,9090);
socket.send(packet);
socket.close();
}
@Test
public void receiver() throws IOException {
DatagramSocket socket = new DatagramSocket(9090);
byte[] buffer = new byte[100];
DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);
socket.receive(packet);
System.out.println(new String(packet.getData(),0,packet.getLength()));
}URL 类的应用
URL(Uniform Resource Locator,统一资源定位符)是对应从互联网某一资源地址。在 Java 网络编程中,java.net.URL 类常用于解析网络地址的各个组成部分。



URL 格式解析
标准格式:http://localhost:8080/examples/beauty.jpg?username=Tom
对应组件:协议 → 主机名 → 端口号 → 资源路径 → 查询参数
public class URLTest {
public static void main(String[] args) {
try {
URL url = new URL("http://localhost:8080/examples/beauty.jpg?username=Tom");
// public String getProtocol() 获取该URL的协议名
System.out.println(url.getProtocol());// http
// public String getHost() 获取该URL的主机名
System.out.println(url.getHost());//localhost
// public String getPort() 获取该URL的端口号
System.out.println(url.getPort());// 8080
// public String getPath() 获取该URL的文件路径
System.out.println(url.getPath());//examples/beauty.jpg
// public String getFile() 获取该URL的文件名
System.out.println(url.getFile());//examples/beauty.jpg?username=Tom
// public String getQuery() 获取该URL的查询名
System.out.println(url.getQuery());//username=Tom
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
}以上就是 Java 网络编程入门篇的详细内容,更多关于 Java 网络编程 Socket 与协议的文章请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









