概述

TCP和UDP是传输层的协议,其中TCP 是面向连接的协议,通信前需要建立连接,通信结束后需要断开连接。 连接建立和断开过程比较复杂,涉及到三次握手和四次挥手。 UDP 是无连接的协议,通信前不需要建立连接,通信结束后也不需要断开连接。

可靠性方面TCP 提供可靠的数据传输,通过序号、确认和重传机制保证数据的可靠性。数据丢失会自动重新传递数据确保数据的完整性和顺序性。UDP 不提供可靠性保证,不会自动进行数据重传。

在Java中实现TCP和UDP通信,你可以使用java.net包中的ServerSocket、Socket类来实现TCP服务器和客户端,以及使用DatagramSocket、DatagramPacket类来实现UDP通信。

TCP

TCP服务端

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

public class TCPServer {
    public static void main(String[] args) {
        int port = 12345; // 定义端口号
        try (ServerSocket serverSocket = new ServerSocket(port)) {
            System.out.println("服务器启动,等待连接...");
            Socket socket = serverSocket.accept(); // 接受客户端连接
            System.out.println("客户端已连接");

            // 读取客户端数据
            BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            String inputLine;
            while ((inputLine = in.readLine()) != null) {
                System.out.println("收到客户端消息: " + inputLine);
                // 响应客户端
                PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
                out.println("服务器响应: " + inputLine);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

TCP客户端

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

public class TCPClient {
    public static void main(String[] args) {
        String hostname = "localhost"; // 服务器地址
        int port = 12345; // 服务器端口号
        try (Socket socket = new Socket(hostname, port)) {
            // 发送数据到服务器
            PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
            BufferedReader console = new BufferedReader(new InputStreamReader(System.in));
            System.out.println("请输入消息发送到服务器:");
            String userInput;
            while (!(userInput = console.readLine()).equals("exit")) {
                out.println(userInput);
                // 读取服务器响应
                BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                System.out.println("服务器响应: " + in.readLine());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

UDP

UDP 服务端

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

public class UDPServer {
    public static void main(String[] args) throws IOException {
        int port = 12345; // 定义端口号
        DatagramSocket socket = new DatagramSocket(port); // 创建DatagramSocket对象用于接收数据包
        byte[] receiveData = new byte[1024]; // 接收数据缓存区
        while (true) {
            DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length); // 创建数据包对象用于接收数据包内容
            socket.receive(receivePacket); // 接收数据包内容到receivePacket对象中
            String sentence = new String(receivePacket.getData(), 0, receivePacket.getLength()); // 将接收到的数据转换成字符串形式,并打印输出到控制台。
            System.out.println("收到客户端消息: " + sentence); // 打印接收到的消息内容。
            String capitalizedSentence = sentence.toUpperCase(); // 将接收到的消息内容转换为大写形式。
            InetAddress IPAddress = receivePacket.getAddress(); // 获取客户端的IP地址。
            int portNumber = receivePacket.getPort(); // 获取客户端的端口号。
            DatagramPacket sendPacket = new DatagramPacket(capitalizedSentence.getBytes(), capitalizedSentence.length(), IPAddress, portNumber); // 创建数据包对象用于发送数据包内容。
            socket.send(sendPacket); // 将大写形式的数据包内容发送给客户端。
        }
    }
}

UDP客户端

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

public class UDPClient {
    public static void main(String[] args) throws IOException {
        String hostname = "localhost"; // 服务器地址
        int port = 12345; // 服务器端口号
        BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in)); // 从控制台读取输入流。
        Dat