Java 网络编程教程_java nio网络编程

yumo66622小时前技术文章4

第一节:网络协议TCP/UDP/SOCKET 介绍


1.1 网络协议基础


网络协议是计算机网络中数据交换的规则和标准。Java主要支持以下协议:


TCP (Transmission Control Protocol)

  • 特点:面向连接、可靠传输、字节流服务
  • 优点:数据完整性保证、顺序传输、流量控制
  • 缺点:建立连接开销大、传输效率相对较低
  • 应用场景:文件传输、邮件发送、网页浏览(HTTP)

UDP (User Datagram Protocol)

  • 特点:无连接、不可靠传输、数据报服务
  • 优点:传输效率高、延迟低、开销小
  • 缺点:不保证数据完整性、可能丢包、无序到达
  • 应用场景:视频流、语音通话、在线游戏

SOCKET 套接字

  • 定义:网络通信的端点,包含IP地址和端口号
  • 类型
  • 流套接字(SOCK_STREAM):基于TCP
  • 数据报套接字(SOCK_DGRAM):基于UDP
  • 作用:应用程序通过网络进行数据交换的接口

1.2 SOCKET 与 TCP/UDP 的关系


1.2.1 SOCKET 是编程接口,TCP/UDP 是传输协议


关键关系

  • SOCKET 是操作系统提供的**编程接口**(API)
  • TCP/UDP 是网络传输的协议标准
  • SOCKET 封装了底层TCP/UDP协议的实现细节
// TCP Socket - 基于TCP协议的Socket编程
Socket tcpSocket = new Socket("localhost", 8080);

// UDP Socket - 基于UDP协议的Socket编程  
DatagramSocket udpSocket = new DatagramSocket(8080);


1.2.4 协议选择对比


特性

TCP Socket

UDP Socket

连接方式

面向连接

无连接

数据传输

字节流

数据报

可靠性

自动重传、确认机制

需要应用层处理

顺序性

保证数据顺序

不保证顺序

开销

较大

较小

适用场景

文件传输、Web请求

实时音视频、游戏


1.3 Java网络编程核心类


// TCP相关
ServerSocket  // 服务器端套接字
Socket        // 客户端套接字

// UDP相关
DatagramSocket      // UDP套接字
DatagramPacket     // 数据包

// 通用
InetAddress        // IP地址处理


第二节:TCP Socket 示例 - 双向通信


2.1 TCP 服务器端代码


import java.io.*;
import java.net.*;

public class TCPServer {
    public static void main(String[] args) {
        final int PORT = 8888;
        
        try (ServerSocket serverSocket = new ServerSocket(PORT)) {
            System.out.println("TCP服务器启动,等待客户端连接...");
            
            Socket clientSocket = serverSocket.accept();
            System.out.println("客户端连接成功: " + clientSocket.getInetAddress());
            
            // 接收客户端消息
            BufferedReader in = new BufferedReader(
                new InputStreamReader(clientSocket.getInputStream()));
            String clientMessage = in.readLine();
            System.out.println("收到客户端消息: " + clientMessage);
            
            // 发送响应
            PrintWriter out = new PrintWriter(
                clientSocket.getOutputStream(), true);
            out.println("Hello,Server");
            
            System.out.println("消息发送完成");
            
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}


2.2 TCP 客户端代码


import java.io.*;
import java.net.*;

public class TCPClient {
    public static void main(String[] args) {
        final String SERVER_IP = "localhost";
        final int PORT = 8888;
        
        try (Socket socket = new Socket(SERVER_IP, PORT)) {
            System.out.println("连接TCP服务器成功");
            
            // 发送消息
            PrintWriter out = new PrintWriter(
                socket.getOutputStream(), true);
            out.println("Hello,Client");
            
            // 接收响应
            BufferedReader in = new BufferedReader(
                new InputStreamReader(socket.getInputStream()));
            String serverResponse = in.readLine();
            System.out.println("收到服务器响应: " + serverResponse);
            
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}


2.3 TCP 运行步骤

2.4 TCP 预期输出


服务器端输出

TCP服务器启动,等待客户端连接...
客户端连接成功: /127.0.0.1
收到客户端消息: Hello,Client
消息发送完成


客户端输出

连接TCP服务器成功
收到服务器响应: Hello,Server


第三节:UDP Socket 示例 - 数据报通信


3.1 UDP 服务器端代码


import java.net.*;

public class UDPServer {
    public static void main(String[] args) {
        final int PORT = 8888;
        
        try (DatagramSocket serverSocket = new DatagramSocket(PORT)) {
            System.out.println("UDP服务器启动,监听端口: " + PORT);
            
            byte[] receiveBuffer = new byte[1024];
            DatagramPacket receivePacket = new DatagramPacket(receiveBuffer, receiveBuffer.length);
            
            serverSocket.receive(receivePacket);
            
            String clientMessage = new String(receivePacket.getData(), 0, receivePacket.getLength());
            System.out.println("收到客户端消息: " + clientMessage);
            System.out.println("客户端地址: " + receivePacket.getAddress().getHostAddress());
            
            String responseMessage = "hello,udp i am server";
            byte[] sendBuffer = responseMessage.getBytes();
            
            DatagramPacket sendPacket = new DatagramPacket(
                sendBuffer, 
                sendBuffer.length, 
                receivePacket.getAddress(), 
                receivePacket.getPort()
            );
            
            serverSocket.send(sendPacket);
            System.out.println("已向客户端发送响应");
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}


3.2 UDP 客户端代码


import java.net.*;

public class UDPClient {
    public static void main(String[] args) {
        final String SERVER_IP = "localhost";
        final int PORT = 8888;
        
        try (DatagramSocket clientSocket = new DatagramSocket()) {
            System.out.println("UDP客户端启动");
            
            String message = "hello,udp i am client";
            byte[] sendBuffer = message.getBytes();
            
            InetAddress serverAddress = InetAddress.getByName(SERVER_IP);
            DatagramPacket sendPacket = new DatagramPacket(
                sendBuffer, 
                sendBuffer.length, 
                serverAddress, 
                PORT
            );
            
            clientSocket.send(sendPacket);
            System.out.println("已向服务器发送消息: " + message);
            
            byte[] receiveBuffer = new byte[1024];
            DatagramPacket receivePacket = new DatagramPacket(receiveBuffer, receiveBuffer.length);
            
            clientSocket.setSoTimeout(3000);
            clientSocket.receive(receivePacket);
            
            String serverResponse = new String(receivePacket.getData(), 0, receivePacket.getLength());
            System.out.println("收到服务器响应: " + serverResponse);
            
        } catch (SocketTimeoutException e) {
            System.out.println("接收超时,服务器可能未响应");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

3.4 UDP 预期输出


服务器端输出

UDP服务器启动,监听端口: 8888
收到客户端消息: hello,udp i am client
客户端地址: 127.0.0.1
已向客户端发送响应


客户端输出

UDP客户端启动
已向服务器发送消息: hello,udp i am client
收到服务器响应: hello,udp i am server


第四节:TCP vs UDP 对比总结


4.1 编程模型对比


方面

TCP Socket

UDP Socket

连接建立

需要accept()和connect()

无连接建立过程

数据传输

使用InputStream/OutputStream

使用DatagramPacket

数据边界

字节流,无边界

数据报,有边界

可靠性

自动处理重传和确认

需要手动处理可靠性

性能

相对较慢

相对较快


4.2 选择建议


选择TCP当

  • 需要可靠的数据传输
  • 数据完整性很重要
  • 传输大量数据
  • 需要维护持久连接

选择UDP当

  • 实时性要求高于可靠性
  • 传输小量数据
  • 需要广播或多播功能
  • 应用层自己处理可靠性

4.3 注意事项


  1. 端口冲突:TCP和UDP可以使用相同的端口号,不会冲突
  2. 资源释放:确保正确关闭所有资源
  3. 异常处理:网络操作必须处理IOException
  4. 超时设置:合理设置连接和读取超时

第五节:扩展练习


5.1 多客户端TCP服务器

// 多线程TCP服务器示例
while (true) {
    Socket clientSocket = serverSocket.accept();
    new Thread(() -> {
        // 处理客户端通信
    }).start();
}


5.2 UDP广播示例

// UDP广播发送
InetAddress broadcastAddress = InetAddress.getByName("255.255.255.255");
DatagramPacket packet = new DatagramPacket(data, data.length, broadcastAddress, port);
socket.send(packet);


5.3 文件传输

基于TCP Socket实现文件传输功能


第六节:常见问题解答


Q1: 为什么UDP不需要建立连接?

A: UDP是无连接协议,每个数据包都是独立的,不需要维护连接状态。


Q2: TCP和UDP可以同时使用同一个端口吗?

A: 可以,TCP和UDP的端口空间是独立的。


Q3: 如何选择TCP还是UDP?

A: 根据应用需求选择:需要可靠性选TCP,需要实时性选UDP。


Q4: 为什么UDP可能更适合实时应用?

A: UDP延迟低,没有重传机制,更适合实时音视频传输。




总结


本教程完整介绍了:

  1. TCP和UDP协议的基本原理和区别
  2. Java中TCP和UDP Socket编程的实现
  3. 完整的双向通信示例代码
  4. 两种协议的适用场景和选择建议
  5. 实际编程中的注意事项

相关文章

java工作流引擎(j-roadflow)快速入门教程

使用j-roadflow java工作流引擎创建一个流程分为两个步骤,创建表单和创建流程。一、创建表单。在流程管理--表单管理下点新建表单即开始创建一个新的表单:点击之后打开表单设计器并弹出表单属性设...

麻省理工女学姐推荐:这是当下最好的Java学习教程了!免费分享

Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征。Java语言作为静态面向对象编程语言的代表...

Java全系列视频教程_java教程视频完整版

资源信息本阶段不需要编程,是让初学者了解程序员这个行业,了解JAVA 的技术体系,用通俗的示例告诉大家什么是编程,并且告诉大家职业如何规划,让初学者不再迷茫。如果已经对自身职业规划比较清晰,可以跳过直...

java入门教程1 - 安装和配置(win和linux)

windows安装和配置安装javahttps://www.oracle.com/java/technologies/javase/javase-jdk8-downloads.html目前大部分项目的...

GitHub上堪称神级的Java技术栈手册火了,看完拿38K妥妥的

前言最近看到很多粉丝问我有没有精品的学习资料,所以我根据这些年的工作经验,加上网络搜集整理了一套针对职场进阶的干货!有很多朋友靠着这些内容进行复习拿到了BATJ等大厂的offer, 还帮助了很多的Ja...