成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

字節一面:TCP和UDP可以使用同一個端口號嗎?

網絡 網絡優化
在網絡通信中,同一臺計算機中,TCP和UDP協議可以使用相同的端口號。每個網絡進程中的套接字地址都是唯一的,由三元組(IP地址,傳輸層協議,端口號)標識。操作系統會根據數據包中的傳輸層協議(TCP或UDP)以及端口號,將接收到的數據正確地交付給相應的應用程序。

首先說答案:可以。怎么理解呢?

我想這個問題要從計算機網絡通信談起,學過計算機網絡的同學,可能都還記得7層或者4層網絡模型,TCP/UDP屬于其中的傳輸層協議,在傳輸層之下是網絡層,網絡層主要通過IP協議來進行通信,這也是我們日常程序開發中能夠接觸到的最底層了,再往下的數據鏈路層和物理層就不是我們這些普通程序員需要關心的了。

圖片圖片

IP

我們先具體看下網絡層。在IP網路層,發送者向接收者傳輸數據的時候,首先需要知道接收者的IP地址,IP地址可以在網絡中唯一標識一臺計算機,然后數據就可以根據IP協議抵達接收者所在的計算機,但是接收者所在的計算機上運行了幾十個程序,計算機應該把這個數據交給哪個程序呢?

端口號

這就像快遞員到達了一棟大樓,下一步它怎么把快遞送到對應的用戶手中呢?聰明的你一定想到了,那就是門牌號。

在計算機中,端口號就是門牌號。計算機的操作系統可以為不同的程序綁定不同的端口號,這樣發送者發送數據時不僅要設置接收者的IP,還要加上接收者的端口號,如此接收者所在的計算機就能把數據轉發給正確的程序了。

TCP/UDP

那么TCP和UDP能不能使用同一個端口號呢?其實在查找端口號之前還有一個傳輸層協議的處理過程,操作系統收到數據后,會先查看數據包使用的是TCP協議還是UDP協議,然后再根據協議進行不同的解析處理,提取到數據后,再轉發到擁有對應端口的程序。

所以TCP和UDP是可以使用相同的端口號的,這在現實中也是常見的。比如 DNS(域名系統)可能需要同時支持 TCP 和 UDP 查詢,這兩種查詢就都可以通過53這個標準端口來進行接收和響應。

但是在同一個傳輸協議下,端口號就不能相同了。如果相同,操作系統的協議棧就不知道該把這個數據包轉給哪個程序了,這種設計會增加很多麻煩。

有的同學可能會觀察到一個現象,那就是同一個計算機上的多個網站可以共享80或者443端口,這其實是應用層的能力,這些網站都寄宿在同一個Web服務器程序上,這個Web服務器程序綁定了80端口,Web服務器收到數據后再根據HTTP協議中的主機頭(可以理解成域名)轉發給不同的網站程序。

還有,如果你的電腦上有多個IP,那就更沒有問題了。不同的IP代表不同的網絡接口,即使都使用TCP協議,只要IP不同,端口號一樣也完全不會沖突。

“IP+傳輸層協議+端口號”就是我們常說的套接字,它能確保數據從一個網絡程序傳遞到另一個網絡程序。大家如果直接使用TCP和UDP編程,就需要手動為套接字設置這幾個參數。

示例

口說無憑,再給大家寫個demo,使用go語言,簡單易懂:

下邊的程序會啟動一個TCP服務器和一個UDP服務器,它們綁定相同的IP和端口號。這里為了方便測試,使用了127.0.0.1這個本機IP,你也可以換成局域網或者公網IP。

package main

import (
    "fmt"
    "net"
    "os"
)

func main() {
    // 定義監聽的端口
    port := "127.0.0.1:12345"

    // 啟動TCP服務器
    go startTCPServer(port)

    // 啟動UDP服務器
    startUDPServer(port)
}

func startTCPServer(port string) {
    // 通過TCP協議監聽端口
    l, err := net.Listen("tcp", port)
    if err != nil {
        fmt.Println("Error listening:", err.Error())
        os.Exit(1)
    }
    defer l.Close()
    fmt.Println("TCP Server Listening on " + port)
    
    // 持續接收TCP數據
    for {
        conn, err := l.Accept()
        if err != nil {
            fmt.Println("Error accepting: ", err.Error())
            os.Exit(1)
        }
        fmt.Println("Received TCP connection")
        conn.Close()
    }
}

func startUDPServer(port string) {
    // 通過UDP協議監聽端口
    addr, err := net.ResolveUDPAddr("udp", port)
    if err != nil {
        fmt.Println("Error resolving: ", err.Error())
        os.Exit(1)
    }

    conn, err := net.ListenUDP("udp", addr)
    if err != nil {
        fmt.Println("Error listening: ", err.Error())
        os.Exit(1)
    }
    defer conn.Close()
    fmt.Println("UDP Server Listening on " + port)

    buffer := make([]byte, 1024)

    // 持續接收UDP數據
    for {
        n, _, err := conn.ReadFromUDP(buffer)
        if err != nil {
            fmt.Println("Error reading: ", err.Error())
            continue
        }
        fmt.Printf("Received UDP packet: %s\n", string(buffer[:n]))
    }
}

然后再創建兩個客戶端,一個是TCP客戶端:

package main

import (
	"fmt"
	"net"
	"os"
)

func main() {
	// 連接到服務器
	conn, err := net.Dial("tcp", "localhost:12345")
	if err != nil {
		fmt.Println("Error connecting:", err.Error())
		os.Exit(1)
	}
	defer conn.Close()

	// 發送數據
	_, err = conn.Write([]byte("Hello TCP Server!"))
	if err != nil {
		fmt.Println("Error sending data:", err.Error())
		return
	}
	fmt.Println("Message sent to TCP server")
}

另一個是UDP客戶端:

package main

import (
	"fmt"
	"net"
	"os"
)

func main() {
	ServerAddr, err := net.ResolveUDPAddr("udp", "localhost:12345")
	if err != nil {
		fmt.Println("Error resolving: ", err.Error())
		os.Exit(1)
	}

	conn, err := net.DialUDP("udp", nil, ServerAddr)
	if err != nil {
		fmt.Println("Error dialing: ", err.Error())
		os.Exit(1)
	}
	defer conn.Close()

	// 發送數據
	_, err = conn.Write([]byte("Hello UDP Server!"))
	if err != nil {
		fmt.Println("Error sending data:", err.Error())
		return
	}
	fmt.Println("Message sent to UDP server")
}

我們可以看到,客戶端發起請求的時候都使用了 localhost:12345 這個目標地址,其中的localhost 實際上是個域名,它會被本地計算機解析為 127.0.0.1。這塊不清楚的可以看我之前寫的這篇:

實際運行效果如下:

圖片圖片

最后總結下:在網絡通信中,同一臺計算機中,TCP和UDP協議可以使用相同的端口號。每個網絡進程中的套接字地址都是唯一的,由三元組(IP地址,傳輸層協議,端口號)標識。操作系統會根據數據包中的傳輸層協議(TCP或UDP)以及端口號,將接收到的數據正確地交付給相應的應用程序。

責任編輯:武曉燕 來源: 螢火架構
相關推薦

2024-03-18 08:21:06

TCPUDP協議

2022-07-26 00:00:02

TCPUDPMAC

2025-03-20 08:40:00

TCPUDP端口

2020-11-10 07:13:44

端口號進程

2019-05-22 09:28:21

TCPUDP端口號

2022-05-10 22:00:41

UDPTCP協議

2019-08-20 10:24:39

HTTPSSSHLinux

2022-08-13 12:07:14

URLHTTP加密

2016-12-15 08:54:52

線程sessionopenSession

2022-12-02 13:49:41

2022-03-30 10:10:17

字節碼棧空間

2022-08-18 17:44:25

HTTPS協議漏洞

2022-10-19 14:08:42

SYNTCP報文

2009-06-09 12:38:12

NetBeanseclipse

2024-09-19 08:51:01

HTTP解密截取

2024-11-26 08:52:34

SQL優化Kafka

2022-10-10 08:13:16

遞歸通用代碼

2019-10-31 13:58:32

阿里電商系統

2021-08-16 20:48:34

嵌入式單片機信息

2024-08-06 10:16:52

Java AgentJava
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 精品一区在线 | 国产丝袜一区二区三区免费视频 | 韩国av一区二区 | 国产亚洲精品一区二区三区 | 黄色av观看 | 日韩精品人成在线播放 | 亚洲久久| 日日噜噜噜夜夜爽爽狠狠视频97 | 九九亚洲 | a网站在线观看 | 亚洲成人日韩 | 成年人精品视频 | 亚洲一区免费视频 | 国产精品中文字幕在线 | 日韩欧美三区 | 自拍视频网 | 日韩欧美国产精品综合嫩v 一区中文字幕 | 一本综合久久 | 欧美日韩国产一区二区三区 | 色综合久久久久 | 国产精品一区视频 | 日本一区二区三区在线观看 | 国产精品久久久久久久久图文区 | 男女视频91 | 精品www| 欧美日韩在线视频一区二区 | 久久精品a| 黄色成人免费在线观看 | 香蕉久久久 | 成人精品久久 | 二区av | 国产精品久久久久久久久久 | 日本在线观看网址 | 天堂色网 | 国产精品一区在线观看 | 高清黄色网址 | 盗摄精品av一区二区三区 | 国产精品成人一区 | 中文字幕免费 | 99久久免费精品国产免费高清 | 日韩在线视频观看 |