最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java?網(wǎng)絡(luò)編程TCP、UDP、HTTP、WebSocket全解

 更新時間:2026年04月21日 09:43:57   作者:派大星酷  
文章主要講解了Java網(wǎng)絡(luò)編程的核心概念及實現(xiàn)方法,涵蓋了TCP和UDP傳輸層協(xié)議、HTTP和WebSocket應(yīng)用層協(xié)議,以及生產(chǎn)環(huán)境中最佳實踐,感興趣的朋友跟隨小編一起看看吧

Java 網(wǎng)絡(luò)編程核心是基于 Socket 實現(xiàn)傳輸層通信(TCP/UDP)基于標(biāo)準(zhǔn)庫 / 框架實現(xiàn)應(yīng)用層協(xié)議(HTTP/WebSocket),覆蓋基礎(chǔ)通信、生產(chǎn)環(huán)境高可用、并發(fā)、異常處理、資源釋放等全場景。

一、核心基礎(chǔ)概念

  1. TCP:面向連接、可靠、有序、字節(jié)流傳輸(如:文件傳輸、接口調(diào)用)
  2. UDP:無連接、不可靠、快速、數(shù)據(jù)報傳輸(如:直播、實時消息)
  3. HTTP:應(yīng)用層協(xié)議,基于 TCP,短連接 / 長連接(Web 接口、網(wǎng)頁)
  4. WebSocket:基于 TCP 的全雙工長連接,解決 HTTP 輪詢弊端(實時通信)
  5. Socket:Java 網(wǎng)絡(luò)編程的基石,是IP + 端口的抽象,分為:
    • ServerSocket:服務(wù)端,監(jiān)聽端口等待連接
    • Socket:客戶端,主動發(fā)起連接

代碼概括:

二、傳輸層編程:TCP(生產(chǎn)級)

基礎(chǔ)原理

  • 三次握手建立連接,四次揮手?jǐn)嚅_
  • 可靠傳輸:超時重傳、擁塞控制、順序保證
  • 適合:需要數(shù)據(jù)不丟失、不亂序的場景

生產(chǎn)級 TCP 服務(wù)端(線程池 + 心跳 + 優(yōu)雅關(guān)閉)

核心優(yōu)化

  1. 線程池異步處理客戶端,避免單線程阻塞
  2. 心跳機制檢測死連接
  3. 優(yōu)雅關(guān)閉:釋放端口、關(guān)閉線程池、中斷線程
  4. 全局異常捕獲 + 日志
  5. 配置化端口、超時時間
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
/**
 * 生產(chǎn)級 TCP 服務(wù)端
 */
public class TcpServer {
    private static final Logger log = LoggerFactory.getLogger(TcpServer.class);
    // 配置化參數(shù)(可抽取到配置文件)
    private static final int PORT = 9999;
    private static final int SO_TIMEOUT = 30000; // 30秒無心跳斷開
    private static final int CORE_POOL_SIZE = 10;
    private final ExecutorService threadPool = Executors.newFixedThreadPool(CORE_POOL_SIZE);
    private ServerSocket serverSocket;
    private volatile boolean isRunning = true;
    public static void main(String[] args) {
        new TcpServer().start();
    }
    /**
     * 啟動服務(wù)端
     */
    public void start() {
        try {
            serverSocket = new ServerSocket(PORT);
            log.info("TCP 服務(wù)端啟動成功,端口:{}", PORT);
            // 注冊優(yōu)雅關(guān)閉鉤子
            Runtime.getRuntime().addShutdownHook(new Thread(this::shutdown));
            while (isRunning) {
                // 阻塞等待客戶端連接
                Socket clientSocket = serverSocket.accept();
                log.info("客戶端連接成功:{}:{}", clientSocket.getInetAddress(), clientSocket.getPort());
                // 線程池處理客戶端請求
                threadPool.execute(new ClientHandler(clientSocket));
            }
        } catch (Exception e) {
            if (isRunning) {
                log.error("TCP 服務(wù)端異常", e);
            }
        }
    }
    /**
     * 優(yōu)雅關(guān)閉
     */
    public void shutdown() {
        try {
            isRunning = false;
            if (serverSocket != null && !serverSocket.isClosed()) {
                serverSocket.close();
            }
            threadPool.shutdown();
            if (!threadPool.awaitTermination(5, TimeUnit.SECONDS)) {
                threadPool.shutdownNow();
            }
            log.info("TCP 服務(wù)端已優(yōu)雅關(guān)閉");
        } catch (Exception e) {
            log.error("服務(wù)端關(guān)閉異常", e);
        }
    }
    /**
     * 客戶端處理器(生產(chǎn)級:心跳、異常處理、資源釋放)
     */
    private static class ClientHandler implements Runnable {
        private final Socket socket;
        private BufferedReader reader;
        private BufferedWriter writer;
        public ClientHandler(Socket socket) {
            this.socket = socket;
            try {
                socket.setSoTimeout(SO_TIMEOUT); // 讀超時(心跳檢測)
                reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            } catch (Exception e) {
                close();
            }
        }
        @Override
        public void run() {
            try {
                String msg;
                while ((msg = reader.readLine()) != null) {
                    log.info("收到客戶端消息:{}", msg);
                    // 心跳包處理
                    if ("heartbeat".equals(msg)) {
                        sendMsg("heartbeat_ack");
                        continue;
                    }
                    // 業(yè)務(wù)消息處理
                    String resp = "服務(wù)端已接收:" + msg;
                    sendMsg(resp);
                }
            } catch (Exception e) {
                log.warn("客戶端連接異常:{}", e.getMessage());
            } finally {
                close();
            }
        }
        /**
         * 發(fā)送消息
         */
        private void sendMsg(String msg) throws IOException {
            writer.write(msg + "\n");
            writer.flush();
        }
        /**
         * 統(tǒng)一釋放資源
         */
        private void close() {
            try {
                if (reader != null) reader.close();
                if (writer != null) writer.close();
                if (socket != null && !socket.isClosed()) socket.close();
                log.info("客戶端連接已關(guān)閉:{}:{}", socket.getInetAddress(), socket.getPort());
            } catch (Exception e) {
                log.error("資源釋放異常", e);
            }
        }
    }
}

生產(chǎn)級 TCP 客戶端(重連 + 心跳 + 異步發(fā)送)

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.net.Socket;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
 * 生產(chǎn)級 TCP 客戶端(自動重連+心跳)
 */
public class TcpClient {
    private static final Logger log = LoggerFactory.getLogger(TcpClient.class);
    private static final String SERVER_HOST = "127.0.0.1";
    private static final int SERVER_PORT = 9999;
    private static final int HEARTBEAT_INTERVAL = 5; // 5秒心跳
    private static final int RECONNECT_INTERVAL = 3; // 3秒重連
    private Socket socket;
    private BufferedReader reader;
    private BufferedWriter writer;
    private volatile boolean isConnected = false;
    private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
    public static void main(String[] args) {
        TcpClient client = new TcpClient();
        client.connect();
        // 測試發(fā)送消息
        client.sendMsg("Hello TCP Server");
    }
    /**
     * 建立連接(失敗自動重連)
     */
    public void connect() {
        while (!isConnected) {
            try {
                socket = new Socket(SERVER_HOST, SERVER_PORT);
                reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
                isConnected = true;
                log.info("連接服務(wù)端成功");
                // 啟動心跳
                startHeartbeat();
                // 監(jiān)聽服務(wù)端消息
                new Thread(this::listenServerMsg).start();
            } catch (Exception e) {
                log.error("連接失敗,{}秒后重試...", RECONNECT_INTERVAL);
                try {
                    TimeUnit.SECONDS.sleep(RECONNECT_INTERVAL);
                } catch (InterruptedException ignored) {}
            }
        }
    }
    /**
     * 心跳機制
     */
    private void startHeartbeat() {
        scheduler.scheduleAtFixedRate(() -> {
            try {
                if (isConnected) {
                    sendMsg("heartbeat");
                    log.debug("發(fā)送心跳包");
                }
            } catch (Exception e) {
                log.error("心跳異常,開始重連");
                disconnect();
                connect();
            }
        }, 0, HEARTBEAT_INTERVAL, TimeUnit.SECONDS);
    }
    /**
     * 監(jiān)聽服務(wù)端消息
     */
    private void listenServerMsg() {
        try {
            String msg;
            while ((msg = reader.readLine()) != null) {
                log.info("收到服務(wù)端消息:{}", msg);
            }
        } catch (Exception e) {
            log.warn("與服務(wù)端斷開連接");
            disconnect();
            connect();
        }
    }
    /**
     * 發(fā)送消息(線程安全)
     */
    public synchronized void sendMsg(String msg) {
        if (!isConnected) {
            log.warn("未連接服務(wù)端,消息發(fā)送失?。簕}", msg);
            return;
        }
        try {
            writer.write(msg + "\n");
            writer.flush();
        } catch (Exception e) {
            log.error("消息發(fā)送異常", e);
            disconnect();
            connect();
        }
    }
    /**
     * 斷開連接
     */
    private void disconnect() {
        isConnected = false;
        try {
            if (reader != null) reader.close();
            if (writer != null) writer.close();
            if (socket != null) socket.close();
        } catch (Exception ignored) {}
    }
}

三、傳輸層編程:UDP(生產(chǎn)級)

基礎(chǔ)原理

  • 無連接,直接發(fā)送數(shù)據(jù)報
  • 速度快,不保證可靠
  • 適合:實時性要求高、可容忍少量丟包的場景

生產(chǎn)級 UDP 服務(wù)端 + 客戶端

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
 * 生產(chǎn)級 UDP(服務(wù)端+客戶端合一)
 */
public class UdpServerClient {
    private static final Logger log = LoggerFactory.getLogger(UdpServerClient.class);
    private static final int PORT = 9998;
    private static final int BUFFER_SIZE = 1024;
    private final ExecutorService threadPool = Executors.newSingleThreadExecutor();
    public static void main(String[] args) {
        UdpServerClient udp = new UdpServerClient();
        udp.startServer();
        udp.sendClientMsg("127.0.0.1", "Hello UDP Server");
    }
    // ==================== UDP 服務(wù)端 ====================
    public void startServer() {
        threadPool.execute(() -> {
            try (DatagramSocket socket = new DatagramSocket(PORT)) {
                log.info("UDP 服務(wù)端啟動,端口:{}", PORT);
                byte[] buffer = new byte[BUFFER_SIZE];
                while (true) {
                    DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
                    socket.receive(packet); // 阻塞接收
                    String msg = new String(packet.getData(), 0, packet.getLength());
                    log.info("收到UDP消息:{} 來自:{}:{}",
                            msg, packet.getAddress(), packet.getPort());
                    // 回寫消息
                    String resp = "UDP 已接收:" + msg;
                    sendUdpMsg(socket, packet.getAddress(), packet.getPort(), resp);
                }
            } catch (Exception e) {
                log.error("UDP 服務(wù)端異常", e);
            }
        });
    }
    // ==================== UDP 客戶端發(fā)送 ====================
    public void sendClientMsg(String host, String msg) {
        try (DatagramSocket socket = new DatagramSocket()) {
            InetAddress address = InetAddress.getByName(host);
            sendUdpMsg(socket, address, PORT, msg);
            log.info("UDP 客戶端發(fā)送消息:{}", msg);
        } catch (Exception e) {
            log.error("UDP 客戶端發(fā)送異常", e);
        }
    }
    /**
     * 統(tǒng)一發(fā)送 UDP 消息
     */
    private void sendUdpMsg(DatagramSocket socket, InetAddress addr, int port, String msg) throws Exception {
        byte[] data = msg.getBytes();
        DatagramPacket packet = new DatagramPacket(data, data.length, addr, port);
        socket.send(packet);
    }
}

四、應(yīng)用層編程:HTTP(生產(chǎn)級)

Java 生產(chǎn)環(huán)境絕不使用原生 HttpURLConnection,推薦兩款標(biāo)準(zhǔn)框架:

  1. OkHttp:輕量、穩(wěn)定、Android / 后端通用
  2. RestTemplate:Spring 生態(tài)標(biāo)準(zhǔn)(微服務(wù)首選)

1. OkHttp 生產(chǎn)級 HTTP 工具類

依賴

<dependency>
    <groupId>com.squareup.okhttp3</groupId>
    <artifactId>okhttp</artifactId>
    <version>4.12.0</version>
</dependency>

生產(chǎn)級代碼(連接池、超時、重試、單例):

import okhttp3.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.TimeUnit;
/**
 * 生產(chǎn)級 OkHttp 工具類(單例+連接池)
 */
public class OkHttpUtil {
    private static final Logger log = LoggerFactory.getLogger(OkHttpUtil.class);
    private static final OkHttpClient CLIENT;
    private static final int MAX_IDLE_CONNECTIONS = 20;
    private static final long KEEP_ALIVE_DURATION = 5L;
    // 單例 OkHttpClient(關(guān)鍵:OkHttp 必須單例,復(fù)用連接池)
    static {
        CLIENT = new OkHttpClient.Builder()
                .connectTimeout(5, TimeUnit.SECONDS)
                .readTimeout(10, TimeUnit.SECONDS)
                .writeTimeout(10, TimeUnit.SECONDS)
                .connectionPool(new ConnectionPool(MAX_IDLE_CONNECTIONS, KEEP_ALIVE_DURATION, TimeUnit.MINUTES))
                .retryOnConnectionFailure(true) // 自動重試
                .build();
    }
    private OkHttpUtil() {}
    /**
     * GET 請求
     */
    public static String get(String url) throws Exception {
        Request request = new Request.Builder()
                .url(url)
                .addHeader("Content-Type", "application/json")
                .build();
        try (Response response = CLIENT.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                throw new Exception("HTTP 請求失敗,狀態(tài)碼:" + response.code());
            }
            return response.body().string();
        }
    }
    /**
     * POST JSON 請求
     */
    public static String postJson(String url, String json) throws Exception {
        RequestBody body = RequestBody.create(json, MediaType.parse("application/json; charset=utf-8"));
        Request request = new Request.Builder()
                .url(url)
                .post(body)
                .build();
        try (Response response = CLIENT.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                throw new Exception("HTTP POST 失敗,狀態(tài)碼:" + response.code());
            }
            return response.body().string();
        }
    }
}

2. Spring RestTemplate 生產(chǎn)級配置

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
/**
 * Spring 生產(chǎn)級 RestTemplate 配置
 */
@Configuration
public class RestTemplateConfig {
    @Bean
    public RestTemplate restTemplate(ClientHttpRequestFactory factory) {
        return new RestTemplate(factory);
    }
    @Bean
    public ClientHttpRequestFactory clientHttpRequestFactory() {
        SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
        factory.setConnectTimeout(5000);
        factory.setReadTimeout(10000);
        // 生產(chǎn)環(huán)境可替換為 OkHttp 工廠,性能更強
        return factory;
    }
}

五、應(yīng)用層編程:WebSocket(生產(chǎn)級)

基礎(chǔ)原理

  • 基于 TCP,全雙工長連接
  • 一次握手,永久通信,服務(wù)端可主動推送消息
  • 適合:聊天、實時通知、大屏數(shù)據(jù)

Spring Boot 生產(chǎn)級 WebSocket

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

生產(chǎn)級代碼(集群可配合 Redis 廣播):

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.atomic.AtomicInteger;
/**
 * 生產(chǎn)級 WebSocket 服務(wù)端
 */
@Component
@ServerEndpoint("/ws/server")
public class WebSocketServer {
    private static final Logger log = LoggerFactory.getLogger(WebSocketServer.class);
    // 在線連接數(shù)(線程安全)
    private static final AtomicInteger ONLINE_COUNT = new AtomicInteger(0);
    // 客戶端集合(線程安全)
    private static final CopyOnWriteArraySet<WebSocketServer> WEB_SOCKET_SET = new CopyOnWriteArraySet<>();
    private Session session;
    /**
     * 連接建立成功
     */
    @OnOpen
    public void onOpen(Session session) {
        this.session = session;
        WEB_SOCKET_SET.add(this);
        ONLINE_COUNT.incrementAndGet();
        log.info("新連接加入,當(dāng)前在線:{}", ONLINE_COUNT.get());
        sendMessage("連接成功");
    }
    /**
     * 連接關(guān)閉
     */
    @OnClose
    public void onClose() {
        WEB_SOCKET_SET.remove(this);
        ONLINE_COUNT.decrementAndGet();
        log.info("連接關(guān)閉,當(dāng)前在線:{}", ONLINE_COUNT.get());
    }
    /**
     * 收到客戶端消息
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        log.info("收到消息:{}", message);
        // 群發(fā)消息
        sendToAll("服務(wù)端廣播:" + message);
    }
    /**
     * 異常處理
     */
    @OnError
    public void onError(Session session, Throwable error) {
        log.error("WebSocket 異常", error);
    }
    /**
     * 發(fā)送消息
     */
    public void sendMessage(String message) {
        try {
            this.session.getBasicRemote().sendText(message);
        } catch (Exception e) {
            log.error("消息發(fā)送失敗", e);
        }
    }
    /**
     * 群發(fā)消息(生產(chǎn)常用)
     */
    public static void sendToAll(String message) {
        for (WebSocketServer ws : WEB_SOCKET_SET) {
            ws.sendMessage(message);
        }
    }
}

啟用 WebSocket

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
@SpringBootApplication
@EnableWebSocket // 開啟 WebSocket
public class NettyApplication {
    public static void main(String[] args) {
        SpringApplication.run(NettyApplication.class, args);
    }
}

六、生產(chǎn)環(huán)境核心最佳實踐(必看)

  1. Socket 必須單例 / 池化
    • TCP 客戶端、OkHttp、RestTemplate 禁止頻繁創(chuàng)建對象,必須復(fù)用連接池
  2. 超時強制設(shè)置
    • 連接超時、讀超時、寫超時,避免線程無限阻塞
  3. 優(yōu)雅關(guān)閉
    • shutdownHook 釋放端口、線程池、Socket,防止端口占用
  4. 心跳機制
    • TCP/WebSocket 必須加心跳,檢測死連接,釋放資源
  5. 線程池替代多線程
    • 禁止為每個客戶端創(chuàng)建新線程,用線程池控制并發(fā)
  6. 異常全覆蓋
    • IO 異常、連接異常、超時異常必須捕獲,不能直接拋出
  7. 生產(chǎn)禁用原生 Socket 高并發(fā)場景
    • 高并發(fā)用 Netty(NIO 框架),性能提升 10~100 倍

由以上可總結(jié)出:

  1. 傳輸層:TCP 可靠(生產(chǎn)用線程池 + 心跳),UDP 快速(實時場景)
  2. 應(yīng)用層:HTTP 用 OkHttp/RestTemplate,WebSocket 用 Spring 封裝
  3. 生產(chǎn)核心:連接池、超時、優(yōu)雅關(guān)閉、心跳、異常處理
  4. 高并發(fā)方案:原生 Socket 僅適合小并發(fā),高并發(fā)必須用 Netty

概念概括

一 Java 網(wǎng)絡(luò)編程本質(zhì)就是兩層:

  1. 傳輸層(TCP、UDP)
    • 基于 Socket 編程
    • 自己定義報文格式、粘包拆包、心跳、重連
  2. 應(yīng)用層(HTTP、HTTPS、WebSocket)
    • 基于 TCP 封裝好的協(xié)議
    • 不用關(guān)心底層連接,只關(guān)心請求 / 響應(yīng)

二、TCP、UDP、HTTP、WebSocket 核心區(qū)別對比表

對比項TCPUDPHTTPWebSocket
連接方式面向連接(三次握手)無連接基于 TCP,短 / 長連接基于 TCP,全雙工長連接
可靠性可靠,不丟包、不亂序不可靠,可能丟包、亂序可靠(依賴 TCP)可靠(依賴 TCP)
傳輸方式字節(jié)流數(shù)據(jù)報請求 - 響應(yīng)模型全雙工,雙向主動推送
開銷高(握手、確認(rèn)、重傳)很高(Header 大)中等(握手一次,后續(xù)幀很小)
速度較慢極快
消息邊界無邊界 → 粘包拆包問題有邊界 → 不會粘包協(xié)議自帶邊界幀結(jié)構(gòu),自帶邊界
服務(wù)端推送需自己實現(xiàn)需自己實現(xiàn)不能主動推送支持主動推送
典型用途文件傳輸、IM、支付、長連接直播、語音、游戲、DNS接口、網(wǎng)頁、RESTful聊天、大屏、實時通知、物聯(lián)網(wǎng)

1. TCP(Transmission Control Protocol)

特點

  • 面向連接,可靠傳輸
  • 有序、重傳、流量控制、擁塞控制
  • 字節(jié)流傳輸,沒有消息邊界
  • 適合對數(shù)據(jù)完整性要求高的場景

生產(chǎn)注意事項(非常重要)

  1. 必須處理粘包 / 拆包TCP 是流,發(fā)送 2 次數(shù)據(jù)可能被合并成 1 次,或 1 次被拆成多段。解決方案:
    • 固定長度
    • 分隔符(\n、\r\n)
    • 長度域 + 報文體(生產(chǎn)標(biāo)準(zhǔn)方案)
  2. 必須設(shè)置 SO_TIMEOUT不設(shè)置會導(dǎo)致線程永久阻塞,OOM 或線程耗盡
  3. 禁止每次 new Socket必須復(fù)用連接、使用連接池
  4. 必須心跳?;?/strong>NAT 超時、防火墻會靜默斷開連接,應(yīng)用層無感知
  5. 必須優(yōu)雅關(guān)閉close () 要放在 finally,避免端口 TIME_WAIT 堆積
  6. 高并發(fā)不能用 BIO并發(fā) > 100 必須用 NIO / Netty,否則線程爆炸

2. UDP(User Datagram Protocol)

特點

  • 無連接,不握手,直接發(fā)
  • 數(shù)據(jù)報模式,自帶消息邊界
  • 速度極快,開銷極小
  • 不保證到達(dá)、順序、重復(fù)

生產(chǎn)注意事項

  1. 不適合支付、交易、重要指令丟包就沒了
  2. 適合實時性 > 可靠性直播、實時游戲、實時監(jiān)控
  3. 無需處理粘包一個 DatagramPacket 就是一個完整包
  4. 可以自己實現(xiàn)簡單可靠機制序號 + 確認(rèn) + 重傳(RTP 就是這么干的)
  5. 包大小不要超過 MTU一般 ≤ 1472 字節(jié),否則會被 IP 層分片,更容易丟包

3. HTTP(HyperText Transfer Protocol)

特點

  • 應(yīng)用層協(xié)議,基于 TCP
  • 請求 - 響應(yīng)模型:客戶端問,服務(wù)端答
  • 無狀態(tài)(需要 Cookie / Token)
  • 1.1 支持長連接,2.0 多路復(fù)用
  • 文本協(xié)議,可讀性強

生產(chǎn)注意事項

  1. 不能服務(wù)端主動推送只能輪詢、長輪詢,效率低
  2. Header 開銷大尤其大量小請求,浪費嚴(yán)重
  3. 必須使用連接池原生 HttpURLConnection 坑多,生產(chǎn)用 OkHttp / RestTemplate
  4. 超時三要素必須設(shè)置連接超時、讀取超時、寫入超時
  5. 重試要謹(jǐn)慎讀接口可以重試,寫接口(POST/PUT)必須保證冪等
  6. HTTPS 必須使用明文傳輸極易被抓包篡改

4. WebSocket

特點

  • 基于 TCP,在 HTTP 握手升級而來
  • 全雙工:客戶端 ↔ 服務(wù)端 隨時發(fā)
  • 一次握手,永久通道
  • 數(shù)據(jù)幀很小,開銷極低
  • 服務(wù)端可以主動推送

生產(chǎn)注意事項

  1. 必須心跳代理、防火墻會斷開空閑連接
  2. 集群環(huán)境要做會話共享多實例部署時,用 Redis 廣播 / STOMP 消息隊列
  3. 注意內(nèi)存泄漏Session 要及時清理,關(guān)閉連接必須移除集合
  4. 避免大文件傳輸不是設(shè)計用來傳文件的
  5. 鑒權(quán)要在握手階段做不要連接建立后再鑒權(quán)

三、它們之間的關(guān)系(一句話串起來)

  1. HTTP 是跑在 TCP 上的應(yīng)用協(xié)議
  2. WebSocket 也是跑在 TCP 上,先用 HTTP 握手,再升級成雙工通道
  3. TCP/UDP 是底層傳輸,你要自己定義協(xié)議
  4. HTTP/WebSocket 是現(xiàn)成協(xié)議,開箱即用

四、生產(chǎn)中怎么選擇?(最實用)

  • 業(yè)務(wù)接口、微服務(wù)調(diào)用HTTP/HTTPS
  • IM、實時通知、大屏WebSocket
  • 自定義長連接、網(wǎng)關(guān)、物聯(lián)網(wǎng)TCP(Netty)
  • 直播、語音、實時游戲UDP(可加可靠層)
  • DNS、心跳探測UDP

到此這篇關(guān)于Java 網(wǎng)絡(luò)編程全解:TCP、UDP、HTTP、WebSocket的文章就介紹到這了,更多相關(guān)Java 網(wǎng)絡(luò)編程全解:TCP、UDP、HTTP、WebSocket內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • springboot整合dubbo設(shè)置全局唯一ID進(jìn)行日志追蹤的示例代碼

    springboot整合dubbo設(shè)置全局唯一ID進(jìn)行日志追蹤的示例代碼

    這篇文章主要介紹了springboot整合dubbo設(shè)置全局唯一ID進(jìn)行日志追蹤,本文通過圖文示例相結(jié)合給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-10-10
  • Maven中pom.xml配置文件詳細(xì)介紹

    Maven中pom.xml配置文件詳細(xì)介紹

    這篇文章主要介紹了Maven中pom.xml配置文件詳細(xì)介紹,具有一定參考價值,需要的朋友可以了解下。
    2017-11-11
  • Springboot使用Spring Data JPA實現(xiàn)數(shù)據(jù)庫操作

    Springboot使用Spring Data JPA實現(xiàn)數(shù)據(jù)庫操作

    Spring Data JPA 是 Spring 基于 Spring Data 框架、在JPA 規(guī)范的基礎(chǔ)上開發(fā)的一個框架,使用 Spring Data JPA 可以極大地簡化JPA 的寫法,本章我們將詳細(xì)介紹在Springboot中使用 Spring Data JPA 來實現(xiàn)對數(shù)據(jù)庫的操作
    2021-06-06
  • Java實現(xiàn)猜數(shù)字小游戲(有次數(shù)限制)

    Java實現(xiàn)猜數(shù)字小游戲(有次數(shù)限制)

    這篇文章主要為大家詳細(xì)介紹了Java實現(xiàn)猜數(shù)字小游戲,有次數(shù)限制,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-05-05
  • SpringBoot錯誤處理流程深入詳解

    SpringBoot錯誤處理流程深入詳解

    在項目開發(fā)中出現(xiàn)異常時很平常不過的事情,我們處理異常也有很多種方式。本文將詳細(xì)為大家講解SpringBoot實現(xiàn)異常處理幾種方法,感興趣的可以學(xué)習(xí)一下
    2022-10-10
  • IDEA快捷鍵和各種實用功能小結(jié)

    IDEA快捷鍵和各種實用功能小結(jié)

    這篇文章主要介紹了IDEA快捷鍵總結(jié)和各種實用功能,包括IDEA中內(nèi)容輔助鍵和快捷鍵,修改自動補全快捷鍵,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-08-08
  • java線程池對象ThreadPoolExecutor的深入講解

    java線程池對象ThreadPoolExecutor的深入講解

    在我們的開發(fā)中“池”的概念并不罕見,有數(shù)據(jù)庫連接池、線程池、對象池、常量池等等。下面這篇文章主要給大家介紹了關(guān)于java線程池對象ThreadPoolExecutor的相關(guān)資料,需要的朋友可以參考借鑒,下面來一起看看吧
    2018-09-09
  • java.sql.SQLException問題解決以及注意事項

    java.sql.SQLException問題解決以及注意事項

    這篇文章主要給大家介紹了關(guān)于java.sql.SQLException問題解決以及注意事項的相關(guān)資料,這個問題其實很好解決,文中通過圖文將解決的辦法介紹的很詳細(xì),需要的朋友可以參考下
    2023-07-07
  • Java開發(fā)之Lombok指南

    Java開發(fā)之Lombok指南

    Lombok是一款Java開發(fā)插件,使得Java開發(fā)者可以通過其定義的一些注解來消除業(yè)務(wù)工程中冗長和繁瑣的代碼,它能夠在編譯源代碼期間自動幫我們生成這些方法,并沒有如反射那樣降低程序的性能。下面我們來詳細(xì)了解一下吧
    2019-06-06
  • springboot應(yīng)用中靜態(tài)資源訪問與接口請求沖突問題解決

    springboot應(yīng)用中靜態(tài)資源訪問與接口請求沖突問題解決

    這篇文章主要介紹了springboot應(yīng)用中靜態(tài)資源訪問與接口請求沖突,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-06-06

最新評論

南涧| 恭城| 禹城市| 府谷县| 内黄县| 互助| 和硕县| 衡水市| 祁阳县| 富源县| 五河县| 涞水县| 沿河| 项城市| 政和县| 永年县| 台北市| 湘潭市| 马鞍山市| 曲阳县| 肃宁县| 洞头县| 鹤庆县| 凤城市| 名山县| 宁武县| 白玉县| 手游| 余庆县| 师宗县| 麻阳| 清涧县| 新余市| 雷山县| 武定县| 合阳县| 比如县| 罗城| 沂水县| 甘孜县| 赞皇县|