單播、廣播、組播和任播

文章目錄

  • 一、單播
  • 二、廣播
  • 三、組播
  • 四、任播
    • 代碼示例:
  • 五、各種播的比較


一、單播

  1. 單播(Unicast)是一種網絡通信方式,它指的是在網絡中從一個源節點到一個單一目標節點對的傳輸模式。單播傳輸時,數據包從發送端直接發送到指定接收端,而不是廣播給網絡中的所有節點或組播給多個指定節點。單播是最常見的網絡通信方式,主要應用于日常的互聯網通信,如訪問網頁、發送電子郵件、文件下載等。
  2. 單播的特點
    在這里插入圖片描述

在這里插入圖片描述
舉個例子

  • 當用戶訪問一個網頁時,用戶的設備會通過單播請求服務器的網頁內容,服務器再單播傳輸響應給用戶設備。
  • 發送電子郵件也是一個單播過程:郵件從發送者的郵件服務器傳輸到接收者的郵件服務器。

二、廣播

  1. 什么是廣播?
    廣播(Broadcast)這種網絡通信方式,用于將數據從一個節點傳輸到同一網絡中的所有其他節點。廣播數據包會被發送到一個特殊的廣播地址,網絡中的所有設備都會接收到這個數據包,不論設備是否需要該信息。這種通信方式一般用于局域網(LAN)中的信息共享。

廣播這個東西,并不是所有的網絡都支持,通常廣播只是在局域網中,IPv6也不只是廣播。在以太網中使用全1的地址,來表示廣播地址。例如255.255.255.255 。在廣播中,發送端并不指定特定的接收方,而是將數據包發送到該網絡中的所有設備。由于廣播會廣泛傳播,在網絡中光標的數據通常是諸如網絡探測和廣告等,這種方式也常被黑客用來進行入侵和攻擊。

在這里插入圖片描述

  1. 廣播的特點
    在這里插入圖片描述

  2. 廣播的類型
    在計算機網絡中,廣播有兩種主要類型

  • 有限廣播(Limited Broadcast):
    使用特殊的IP地址255.255.255.255
    僅在發送數據包的子網中傳播,不能跨越路由器
    例如:DHCP請求使用有限廣播,因為客戶端不知道服務器的IP地址
  • 定向廣播(Directed Broadcast)
    使用的是子網廣播地址,例如在192.168.1.0/24子網中的定向廣播地址是192.。168.1.255 。
    定向廣播包只會被發送到特定的子網,因此可以跨越一些允許定向廣播的路由器
    通常用于特定子網中發送廣播信息,二人不是整個局域網
  • 假如有一個網絡192.168.1.0/224,它的廣播地址是192.168.1.255,那么向1192.168.1.255發送的數據包會被該子網中的所有設備接收
    如果有設備A向192.168.1.55發送廣播包,那么192.168.1.0/24子網內的所有設備都會接收到該數據包
    使用ping255.255.255.255命令(有限廣播),可以測試網絡中是否有設備響應,常用于網絡調試。
  1. 廣播的應用場景
    在這里插入圖片描述

  2. 廣播在不同協議中的使用

  • IP v4協議:IPv4中支持廣播,有專門的廣播地址
  • IPv6協議:IPv6取消了廣播功能,代之以組播(Multicast)和任播(Anycast)通信方式,組播比廣播高效且對資源利用更優化。
  1. 代碼示例
    下面是一個用C++實現UDP廣播的示例代碼,這個程序將創建一個UDP套接字,并向局域網內的廣播地址發送消息。代碼將消息廣播到默認的局域網廣播地址(如255.255.255.255或某個特定的子網廣播地址,比如192.168.1.255)

注:運行廣播代碼時,請確保防火墻允許廣播包的發送,否則可能會被攔截。另外,這段代碼需要在支持BSD套接字的環境中允許,比如Linux或Windows。

//Linux版本
#include <iostream>
#include <cstring>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <unistd.h>
using namespace std;#define BROADCAST_PORT 8888   //發送廣播的端口
#define BROADCAST_IP "255.255.255.255"    //廣播地址int main() {//創建UDP套接字int sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (sockfd < 0) {perror("socket");return -1;}//啟用廣播選項int BroadcastEnable = 1;//啟用廣播if(setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &BroadcastEnable, sizeof(BroadcastEnable))){close(sockfd);perror("setsockopt");return -1;}//配置廣播地址struct sockaddr_in broadcastAddr;       //配置廣播地址memset(&broadcastAddr, 0, sizeof(broadcastAddr));broadcastAddr.sin_family = AF_INET;broadcastAddr.sin_addr.s_addr = inet_addr(BROADCAST_IP);broadcastAddr.sin_port = htons(BROADCAST_PORT);//廣播的消息const char* message="HEllo,this is a broadcast message!";//發送廣播消息int sendResult=sendto(sockfd, message, strlen(message),0,(struct sockaddr*)&broadcastAddr,sizeof(broadcastAddr));if(sendResult<0){perror("send Faliure!");}else{cout<<"send success!"<<"and sent:"<<message<<endl;}//關閉套接字close(sockfd);return 0;
}
//Windows版本
#include <iostream>
#include <cstring>
#include <winsock2.h>  //Windows套接字庫
#include <Ws2tcpip.h>  //Windows套接字IPv4地址庫using namespace std;#pragma comment(lib, "Ws2_32.lib")  //自動連接ws2_32.lib庫#define BROADCAST_PORT 8888   //發送廣播的端口
#define BROADCAST_IP "255.255.255.255"    //廣播地址int main() {//初始化Winsock庫WSADATA wsaData;if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {cerr << "WSAStartup failed." <<WSAGetLastError()<< endl;return -1;}//創建UDP套接字SOCKET sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (sockfd < 0) {perror("socket");return -1;}//啟用廣播選項int BroadcastEnable = 1;//啟用廣播if(setsockopt(sockfd,SOL_SOCKET,SO_BROADCAST,(char *)&BroadcastEnable,sizeof(BroadcastEnable))){cerr<<"setsockopt failed."<<WSAGetLastError()<<endl;closesocket(sockfd);WSACleanup();return -1;}//配置廣播地址struct sockaddr_in broadcastAddr;       //配置廣播地址memset(&broadcastAddr, 0, sizeof(broadcastAddr));broadcastAddr.sin_family = AF_INET;broadcastAddr.sin_addr.s_addr = inet_addr(BROADCAST_IP);broadcastAddr.sin_port = htons(BROADCAST_PORT);//廣播的消息const char* message="HEllo,this is a broadcast message!";//發送廣播消息int sendResult=sendto(sockfd, message, strlen(message),0,(struct sockaddr*)&broadcastAddr,sizeof(broadcastAddr));if(sendResult<0){perror("send Faliure!");}else{cout<<"send success!"<<"and sent:"<<message<<endl;}//關閉套接字closesocket(sockfd);return 0;
}

三、組播

  1. 什么是組播多播?
    組播和多播實際上是同一個概念,兩者只是翻譯上的差異。組播(或多播)也是一種網絡通信方法,允許數據只發送一次,但可以由多臺主機接收。其主要應用于需要多個接收方實時同步數據的場景,比如在線視頻直播、網絡游戲、股票行情等
    組播通常用于局域網,因為許多路由器和網絡設備(特別是家用和小型網絡設備)不支持跨互聯阿的組播路由。此外,組播的管理和傳輸在局域網中更為高效和可控。。不過,大型企業或互聯網服務提供商可能在其內部網絡中使用組播、以實現高效的數據分發。

在這里插入圖片描述

  1. 組播的原理
    在這里插入圖片描述
    在這里插入圖片描述
  • 具體來說,在一個局域網中的組播過程如下:
    1.假設在局域網內有5臺主機:A、B、C、D、E
    2.通過分配一個組播地址和端口(比如239.255.0.1:8888)來定義組
    3.現在,如果主機A、B和C加入了這個組播組(即訂閱了233.255.0.。1:8888的組播消息),那么D和E不會收到該組播消息,因為它們沒有加入該組.
    4.當A發送一條組播消息到239.255.0.1:8888時,B和C會接收這條消息,而D和E不會收到,因為組播只會將數據發送給加入了該組播地址的主機
    5.組播的IP和端口是程序自己隨意選擇的(避開常用端口,要大于1024),只要在239.0.0.0到239.。255.。255.255這個范圍內就可以。
  1. 代碼實現(基于Windows版本)
    發送端

#include <iostream>
#include <winsock2.h>
#include <ws2tcpip.h>#pragma comment(lib, "Ws2_32.lib")using namespace std;int main()
{//初始化WinSockWSADATA wsaData;WSAStartup(MAKEWORD(2, 2), &wsaData);if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2){WSACleanup();return 1;}//創建UDP套接字SOCKET sendsock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);if(sendsock==INVALID_SOCKET){cerr<<"socket error"<<endl;WSACleanup();return -1;}//設置組播地址和端口sockaddr_in multicastAddr;multicastAddr.sin_family = AF_INET;multicastAddr.sin_addr.s_addr = inet_addr("239.255.0.1");multicastAddr.sin_port = htons(8888);//設置套接字為可廣播,以確保數據可以通過廣播發送到組播地址int ttl = 1;setsockopt(sendsock, IPPROTO_IP, IP_MULTICAST_TTL, (char*)&ttl, sizeof(ttl));//發送組播消息const char* message = "Hello, multicast!";int sendResult = sendto(sendsock, message, strlen(message), 0, (sockaddr*)&multicastAddr, sizeof(multicastAddr));if(sendResult==SOCKET_ERROR){cerr<<"sendto error"<<endl;closesocket(sendsock);WSACleanup();return -1;}cout<<"sendto success and message is:"<<message<<endl;//關閉套接字closesocket(sendsock);WSACleanup();}

接收端

#include <iostream>
#include <winsock2.h>
#include <ws2tcpip.h>#pragma comment(lib, "Ws2_32.lib")using namespace std;int main()
{//初始化WinSockWSADATA wsaData;WSAStartup(MAKEWORD(2, 2), &wsaData);if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2){WSACleanup();return 1;}//創建UDP套接字SOCKET recvsock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);if(recvsock==INVALID_SOCKET){cerr<<"socket error"<<endl;WSACleanup();return -1;}//綁定組播地址和端口sockaddr_in recvAddr;recvAddr.sin_family = AF_INET;recvAddr.sin_addr.s_addr = INADDR_ANY;recvAddr.sin_port = htons(8888);if(bind(recvsock,(sockaddr*)&recvAddr,sizeof(recvAddr))==SOCKET_ERROR){cerr<<"bind error"<<endl;closesocket(recvsock);WSACleanup();return -1;}//加入組播組ip_mreq multicastRequest;multicastRequest.imr_multiaddr.s_addr = inet_addr("239.255.0.1");//組播地址multicastRequest.imr_interface.s_addr = INADDR_ANY;   //本地任意接口if(setsockopt(recvsock,IPPROTO_IP,IP_ADD_MEMBERSHIP,(char *)&multicastRequest,sizeof(multicastRequest))){cerr<<"setsockopt error"<<endl;closesocket(recvsock);WSACleanup();return -1;}//接收組播消息char recvBuf[1024];sockaddr_in senderAddr;int senderAddrLen = sizeof(senderAddr);int recvlen= recvfrom(recvsock,recvBuf,sizeof(recvBuf),0,(sockaddr*)&senderAddr,&senderAddrLen);if(recvlen>0){recvBuf[recvlen] = '\0';cout<<"receive message:"<<recvBuf<<endl;}else{cerr<<"recvfrom error"<<endl;}//退出組播組setsockopt(recvsock,IPPROTO_IP,IP_DROP_MEMBERSHIP,(char *)&multicastRequest,sizeof(multicastRequest));//關閉套接字closesocket(recvsock);WSACleanup();return 0;;
}
  • 注意事項
    1.組播地址選擇,在局域網中,239.0.0.0到239.255.255.255是專用組播地址,通常用于本地組播
    2.TTL設置:通過設置TTL(Time-To_Live)為1,可確保組播消息不會被路由器轉發到其他網段
int ttl = 1;
setsockopt(sendsock, IPPROTO_IP, IP_MULTICAST_TTL, (char*)&ttl, sizeof(ttl));

IPPORTTO_IP:這個參數指定了將要設置對的選項所需的協議級別,IPPORTTO_IP表示這是IPv4協議級別的選項。對于IPv6,相應的常量是IPPORTTO_IPV6 。
IP_MULTICAST_TTL:這是要設置的選項名,IP_MULTICAST_TTL用于指定多播數據包的生存時間(TTL),TTL定義了數據包在網絡中可以經過的最大路由器數(或跳數)。每當數據包經過一個路由器時,其TTL值減1.當TTL值減到0時,數據包被丟棄。

if(setsockopt(recvsock,IPPROTO_IP,IP_ADD_MEMBERSHIP,(char *)&multicastRequest,sizeof(multicastRequest))){cerr<<"setsockopt error"<<endl;closesocket(recvsock);WSACleanup();return -1;}
  • sock:套接字描述符
  • IPPORTTO_IP:指定選項所在的協議層。
  • IP_ADD_MEMBERSHIP:這是要設置選項的名稱。它告訴系統,我們想要將一個套接字加入到一個多播組中
  • &multicast_request:指向一個ip_mreq結構的指針,該結構包含了多播組的地址以及本地接口的地址(或者是一個特殊的值來表示所有接口)。這個結構定義了套接字將要加入的多播組。
  • ip_mreq結構通常定義如下(在<netinet/in.h>或類似頭文件中):
struct ip_mreq{struct in_addr imr_umltiaddr;//多播組的IP地址struct in_addrr imr_interface;//本地接口的IP地址,或INADDR_ANY表示所有接口
}
  • sizeof(multicast_request):指定了multicast_request結構的大小,以字節為單位。
  1. 代碼實現(基于Linux)
//服務端
#include <iostream>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
using namespace std;#define PORT 8080
#define MAX_SIZE 1024int main()
{//創建UDP套接字int sendsock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);if(sendsock<0){cerr<<"socket error"<<endl;return -1;}//設置組播地址和端口sockaddr_in multicastAddr;multicastAddr.sin_family = AF_INET;multicastAddr.sin_addr.s_addr = inet_addr("239.255.0.1");multicastAddr.sin_port = htons(8888);//設置套接字為可廣播,以確保數據可以通過廣播發送到組播地址int ttl = 1;setsockopt(sendsock, IPPROTO_IP, IP_MULTICAST_TTL, (char*)&ttl, sizeof(ttl));//發送組播消息const char* message = "Hello, multicast!";int sendResult = sendto(sendsock, message, strlen(message), 0, (sockaddr*)&multicastAddr, sizeof(multicastAddr));if(sendResult<0){cerr<<"sendto error"<<endl;close(sendsock);return -1;}cout<<"sendto success and message is:"<<message<<endl;//關閉套接字close(sendsock);return 0;
}
#include <iostream>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
using namespace std;#define PORT 8080
#define MAX_SIZE 1024int main()
{//創建UDP套接字int recvsock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);if(recvsock<0){cerr<<"socket error"<<endl;return -1;}//綁定組播地址和端口sockaddr_in recvAddr;recvAddr.sin_family = AF_INET;recvAddr.sin_addr.s_addr = INADDR_ANY;recvAddr.sin_port = htons(8888);if(bind(recvsock,(sockaddr*)&recvAddr,sizeof(recvAddr))<0){cerr<<"bind error"<<endl;close(recvsock);return -1;}//加入組播組ip_mreq multicastRequest;multicastRequest.imr_multiaddr.s_addr = inet_addr("239.255.0.1");//組播地址multicastRequest.imr_interface.s_addr = INADDR_ANY;   //本地任意接口//接收組播消息char recvBuf[1024];sockaddr_in senderAddr;socklen_t senderAddrLen = sizeof(senderAddr);int recvlen= recvfrom(recvsock,recvBuf,MAX_SIZE,0,(sockaddr*)&senderAddr,&senderAddrLen);if(recvlen>0){recvBuf[recvlen] = '\0';cout<<"receive message:"<<recvBuf<<endl;}else{cerr<<"recvfrom error"<<endl;}//退出組播組setsockopt(recvsock,IPPROTO_IP,IP_DROP_MEMBERSHIP,(char *)&multicastRequest,sizeof(multicastRequest));//關閉套接字close(recvsock);
}

四、任播

  1. 什么是任播?
    任播(Anycast)是指多個服務器或節點共享一個IP地址,通過網絡協議中的路由機制,用戶的請求自動選擇距離最近或最優的服務器進行響應。與傳統的單播(Unicast)和組播(Multicast)不同,任播的核心在于“發送到最近的一個”

任播與組播的區別:在組播中,消息會被發送到一組所有訂閱該IP地址的節點。但在任播中,消息只會到達同一IP地址下的一個最優節點。
任播可以使用任何可路由的IP地址,通常是常規的單播地址(A類、B類或C類IP地址),而不是D類地址。
任播實現的關鍵在于多個主機共享同一單播IP地址,通過路由協議(例如BGP或OSPF)來決定最近或最佳路徑,而不是通過適用特殊的IP地址類被來實現。

  1. 任播的特點
    在這里插入圖片描述

  2. 任播的原理

在這里插入圖片描述

  1. 任播最優路由決策的過程
    任播的最優路由通常由BGP(邊界網關協議)或OSPF(開放式最短路徑優先協議)等網絡路由協議來實現。以下是最優路由的決策過程
  • 地理距離和路徑開銷:在同一任播IP地址的情況下,路由器根據用戶的地理位置選擇最短路徑或最低延遲的路徑,以減少數據傳輸時間

  • 網絡延遲:當路徑開銷類似時,路由器會優先選擇網絡延遲較低的路徑。網絡延遲可以通過探測或協議交換獲得。

  • 路徑穩定性:路由協議會優先選擇路徑穩定性較高的節點,路徑的不穩定性可能會導致路由頻繁更改,從而增加網絡開銷。

  • 路由協議的計算與更新:在BGP等動態路由協議中,節點定期交換路由信息,一旦有節點發生變化(如故障、延遲增加),路由表會根據新的路由哦條件進行更新

  • 負載平衡機制:如果多個節點的延遲相似,路由器會分配請求給不同節點,以實現負載平衡。這種策略也用于避免某個節點出現瓶頸。

舉個例子:互聯網中的任播-----Google DNS服務
假設你在中國訪問Google的公共DNS服務器(如IP地址8.8.8.8).Google在全球多個地點(美國、歐洲、亞洲等)部署了多個共享這個IP地址的DNS服務器,這些服務器都配置為任播節點。

  1. 當你請求訪問8.8.8.8時,路由器會根據你的地理位置和當前的網絡狀況,選擇距離最近或響應最快的服務器節點來處理請求。例如,你的請求會被引導到位于亞洲的一個GoogleDNS服務器,而不是到美國或歐洲的服務器。
  2. 這樣做的好處是降低了請求延遲,用戶可以更快的速度獲得DNS解析結果,同時,入股亞洲的服務器出現故障,請求會自動轉向其他位置的服務器,確保服務的高可用性。
    也就是說:在互聯網中的任播應用,通過全局BGP協議實現,將全球用戶的請求引導至最近的服務器節點。
  • 再舉個例子就是
  • 主句A在北京,而主機B在石家莊、C和D在上海、E在硅谷。所有節點BCDE都監聽同一個任播地址239.255.255.250和端口8080.
  • 當A發送UDP消息到任播地址239.255.255.250:8080時,路由協議會選擇一個最優路徑,將消息轉發給其中距離最近的一個節點,而不是多個節點。

在這里插入圖片描述
在這里插入圖片描述

代碼示例:

  • 場景設定
    假設網絡已經配置支持任播
    發送方主機A位于北京,向任播地址239.255.255.250發送消息,端口為8080
    接收方主機(B、C、D、E)都監聽239.255.255.250:8080上。
    我們可以使用UDP套接字實現該功能,并且需要網絡配置支持任播路徑選擇,比確保消息能正確到達距離最近的節點。
  1. 發送方代碼(主機A)–sender.cpp
    發送方會向任播IP地址239.255.255.250的端口8080發送UDP消息。
#include <iostream>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <unistd.h>
#include <cstring>
using namespace std;#define ANYCAST_IP "239.255.255.250"   //任播IP地址
#define PORT 8080int main() {int sockdf;struct sockaddr_in servaddr;//創建UDP套接字sockdf = socket(AF_INET, SOCK_DGRAM, 0);if (sockdf < 0) {perror("socket create Failure!");return -1;}//設置目標地址memset(&servaddr, 0, sizeof(servaddr));servaddr.sin_family = AF_INET;servaddr.sin_port=htons(PORT);if(inet_pton(AF_INET, ANYCAST_IP, &servaddr.sin_addr)<=0)//任播地址{perror("inet_pton Failure!");clsoe(sockdf);return -1;}//準備消息內容const char* message="Hello from A(BeiJing)";int msg_len=strlen(message);//發送消息if(sendto(sockfd,message,msg_len,0,((struct sockaddr*)&servaddr),sizeof(servaddr))<0){perror("sendto Failure!");close(sockdf);return -1;}cout<<"Message send to"<<ANYCAST_IP<<":"<<PORT<<endl;//關閉套接字close(sockdf);return 0;
}
  1. 接收方代碼(主機B/C/D/E)–receiver.cpp
    接收方監聽在任播IP地址239.255.255.250和端口8080上,等待來自發送方的UDP消息
#include <iostream>
#include <cstring>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
using namespace std;#define ANYCAST_IP "239.255.255.250"   //任播IP地址
#define PORT 8080int main()
{int sockfd;struct sockaddr_in servaddr,clientaddr;//創建UDP套接字sockfd = socket(AF_INET,SOCK_DGRAM,0);if(sockfd < 0){cout << "create socket error" << endl;return -1;}//設置地址復用選項,允許多個節點綁定到相同的端口int opt=1;if(setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt))){cout << "set socket option error" << endl;close(sockfd);return -1;}//設置服務器地址memeset(&servaddr,0,sizeof(servaddr));servaddr.sin_family = AF_INET;servaddr.sin_port = htons(PORT);servaddr.sin_addr.s_addr = inet_addr(ANYCAST_IP);//綁定套接字來任播地址if(bind(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr)) < 0){cout << "bind socket error" << endl;close(sockfd);return -1;}//接收數據char buf[1024];socklen_t len = sizeof(clientaddr);cout<<"Receiver listening on "<<ANYCAST_IP<<":"<<PORT<<endl;while(true){int n = recvfrom(sockfd,buf,sizeof(buf)-1,0,(struct sockaddr *)&clientaddr,&len);if(n<0){perror("recvfrom");break;}buf[n] = '\0';cout<<"Received message :"<<buf<<"from "<<inet_ntoa(clientaddr.sin_addr)<<":"<<ntohs(clientaddr.sin_port)<<endl;}//關閉套接字close(sockfd);return 0;
}
  1. 代碼說明和重要的函數參數
  • 發送方:通過UDP套接字向任播地址239.255.255.250:8080發送消息

  • 接收方:通過UDP套接字綁定到相同的任播地址和端口號239.255.255.250:8080,監聽并接收消息。

  • a. 在多個接收方節點(如B、C、D、E)上運行receiver.cpp,并確保網絡配置支持任播

  • b. 在發送方節點A上運行sender.cpp發送消息

    • 難點代碼
//設置地址復用選項,允許多個節點綁定到相同的端口int opt=1;if(setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt))){cout << "set socket option error" << endl;close(sockfd);return -1;}

(1)sockfd:這是套接字文件描述符,socket()函數返回的值。setsockopt將對這個套接字應用配置選項。
(2)SOL_SOCKET:這是套接字層的選項類型,用于指定選項在套接字級別(例如,SO_REUSEADDR、SO_KEEPALIVE等)。當你想要設置通用的套接字選項(而不是協議特定的選項)時,會將此參數設置為SOL_SOCKET。
(3)SO_REUSEADDR:這是具體的選項標志,表示地址重用。它允許一個本地端口可以被多個套接字綁定,特別是在以下場景中使用:
···
····服務器快速重啟:如果服務器進程使用某個端口并意外終止,那么在短時間內重新啟動該進程時,端口可能還被操作系統標記為“正在使用”,SO_REUSEADDR可以使端口立即可用。
···多播和任播:多個進程可用監聽同一個端口,這對于多播和任播應用非常重要,因為多個服務器實例可能同時監聽同一端口來接收數據。
···端口共享:允許多個套接字同時綁定到同一IP地址和端口,但其中只有一個會接收傳入數據。
···&opt:這是指向opt變量的指針,表示SO_REUSEADDR的值。我們將其設置為1(即opt=1),表示啟用端口重用。若將其設置為0,則表示禁用端口重用。
···sizeof(opt):指定opt的大小,用于告訴setsockopt函數opt變量的長度。

  1. 預期結果
    在正確配置任播的情況下,只有一個接收方節點(例如距離A最近的B節點)會接收到消息,并在控制臺上打印發送方A的消息內容。這是因為任播路由的設計會自動將消息引導到最優路徑的單一節點。

五、各種播的比較

特性單播(Unicast)廣播(Broadcast)任播(Anycast)組播(Multicast)
地址類型A、B、C類IP地址D類地址(以255.255.255.255結尾)A、B、C類IP地址D類地址(224.0.0.0-239.255.255.255)
數據傳輸范圍一個發送者到一個接收者一個發送者到同一網絡內的所有接收者一個發送者到多個節點之一,選擇最近的一個節點一個發送者到指定組內的多個接收者
數據傳輸效率效率低,需要多個單獨的傳輸效率低,所有設備都接收,無論是否需要效率較高,只發送到最優接收者效率較高,只發送到訂閱的接收者
應用場景點對點通信,例如CS模型局域網中的廣播(如ARP請求)CDN、DNS等分布式服務,將流量引導到最近節點視頻會議、IPTV、在線直播等
IP地址范圍常規單播IP地址(如A類、B類、C類)子網廣播(如192.168.1.255),或全網廣播常規單播IP地址(如A類、B類、C類)D類地址范圍(224.0.0.0-239.255.255.255)
路由實現常規路由、根據目標單個IP地址不路由,一般局限于局域網內通過路由協議選擇最近或最優的路徑依靠多播路由協議(如PIM)
典型協議TCP、UDPUDPBGP(用于選擇最近節點)IGMP、PIM
適用范圍適用于需要專用通信的場景局限于局域網廣域網和局域網均適用,要求網絡支持任播配置局域網和廣域網均適用
優勢通信明確、安全性高易于實現,無需復雜配置實現負載均衡、提高服務性能節省帶寬、優化數據傳輸效率
缺點不適用于大規模接收者的通信消耗帶寬、增加不必要的網絡流量依賴路由協議支持,配置復雜需要額外的組播路由配置

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/73182.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/73182.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/73182.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【實戰】deepseek數據分類用戶評論數據

在平時的工作中&#xff0c;我們會遇到數據分類的情況&#xff0c;比如將一些文本劃分為各個標簽。如果人工分類這塊的工作量將是非常大&#xff0c;而且分類數據的準確性也不高。我們需要用到一些工具來實現。提高效率的同時也提高準確率。 1.示例數據 用戶ID 時間戳 評論場…

技術視角解讀:游戲出海如何借助AWS全球架構突破性能與合規瓶頸

【場景痛點】 某二次元卡牌手游團隊在東南亞市場遭遇聯機延遲投訴率高達37%&#xff0c;日本地區因數據合規問題面臨下架風險。在傳統IDC架構下&#xff0c;運維團隊需要同時管理3個區域的物理服務器&#xff0c;版本更新耗時長達6小時。 【技術架構升級】 通過AWS Local Zones…

【JavaEE】網絡編程socket

1.????前言~&#x1f973;&#x1f389;&#x1f389;&#x1f389; Hello, Hello~ 親愛的朋友們&#x1f44b;&#x1f44b;&#xff0c;這里是E綿綿呀????。 如果你喜歡這篇文章&#xff0c;請別吝嗇你的點贊????和收藏&#x1f4d6;&#x1f4d6;。如果你對我的…

第16屆藍橋杯單片機4T模擬賽三

本次模擬賽涉及的模塊&#xff1a;基礎三件套&#xff08;Led&Relay&#xff0c;按鍵、數碼管&#xff09; 進階單件套&#xff08;pcf8591的AD模塊&#xff09; 附件&#xff1a; 各模塊底層代碼在文章的結尾 一、數碼管部分 1.頁面1 頁面1要顯示的格式是&#xff1a; …

網絡華為HCIA+HCIP IPv6

目錄 IPv4現狀 IPv6基本報頭 IPv6擴展報頭 IPv6地址 IPv6地址縮寫規范 ?編輯 IPv6地址分配 IPv6單播地址分配 IPv6單播地址接口標識 IPv6常見單播地址 - GUA &#xff08;2 / 3 開頭&#xff09; IPv6常見單播地址 - ULA IPv6常見單播地址 - LLA IPv6組播地…

基于YOLOv8深度學習的智能小麥害蟲檢測識別系統

作者簡介&#xff1a;Java領域優質創作者、CSDN博客專家 、CSDN內容合伙人、掘金特邀作者、阿里云博客專家、51CTO特邀作者、多年架構師設計經驗、多年校企合作經驗&#xff0c;被多個學校常年聘為校外企業導師&#xff0c;指導學生畢業設計并參與學生畢業答辯指導&#xff0c;…

Mac:Maven 下載+安裝+環境配置(詳細講解)

&#x1f4cc; 下載 Maven 下載地址&#xff1a;https://maven.apache.org/download.cgi &#x1f4cc; 無需安裝 Apache官網下載 Maven 壓縮包&#xff0c;無需安裝&#xff0c;下載解壓后放到自己指定目錄下即可。 按我自己的習慣&#xff0c;我會在用戶 jane 目錄下新建…

XSS-labs(反射型XSS) 靶場 1-13關 通關

目錄 前言 XSS漏洞概述 XSS漏洞分類 通關日記 level1 分析 解題 ?level2 分析 解題 方法一&#xff1a;閉合標簽 方法二&#xff1a;閉合雙引號 level3 分析 解題 level4 分析 解題 level5 分析 解題 level6 分析 解題 level7 分析 解體 level8 …

GPT-5 將免費向所有用戶開放?

GPT-5 將免費向所有用戶開放&#xff1f; 硅谷知名分析師 Ben Thompson 最近與 OpenAI CEO Sam Altman 進行了一場深度對談&#xff0c;其中Sam Altman透漏GPT-5將免費向大家發放。 OpenAI 這波操作可不是一時沖動&#xff0c;而是被逼出來的。DeepSeek 這個新秀橫空出世&am…

【雜記二】git, github, vscode等

一、前言 暫時空著... 二、git 2.1 可能的疑問 1. VSCode 項目名和 GitHub 倉庫名是否需要一致&#xff1f; 不需要一致。 VSCode 項目名&#xff08;也就是你本地的文件夾名字&#xff09;和 GitHub 倉庫名可以不一樣。 Git 是一個分布式版本控制系統&#xff0c;它主要關…

數學愛好者寫的編程系列文章

作為一個數學愛好者&#xff0c;我大學讀的專業卻不是數學專業&#xff0c;而是跟計算機有關的專業。原本我對編程一竅不通&#xff0c;平時上課也是在看數學文獻&#xff0c;作業基本靠同學&#xff0c;考試及格就行。不過后來因為畢業的壓力&#xff0c;我還是擁抱編程了&…

FPGA 以太網通信(四)網絡視頻傳輸系統

一、網絡視頻傳輸系統 網絡視頻傳輸系統使用ov5640攝像頭采集數據&#xff0c;通過組件UDP幀將視頻數據實時傳輸給上位機。 ov5640視頻傳輸帶寬 像素分辨率設為640x480&#xff0c;幀率設為60幀&#xff0c;像素格式為RGB565&#xff0c;傳輸帶寬為 640 x 480 x 16bit x 60 fps…

[leetcode]1631. 最小體力消耗路徑(bool類型dfs+二分答案/記憶化剪枝/并查集Kruskal思想)

題目鏈接 題意 給定 n m n\times m nm地圖 要從(1,1) 走到 (n,m) 定義高度絕對差為四聯通意義下相鄰的兩個點高度的絕對值之差 定義路徑的體力值為整條路徑上 所有高度絕對差的max 求所有路徑中 最小的路徑體力值是多少 方法1 這是我一開始自己寫的記憶化剪枝 比較暴力 時…

DeepSeek寫打臺球手機小游戲

DeepSeek寫打臺球手機小游戲 提問 根據提的要求&#xff0c;讓DeepSeek整理的需求&#xff0c;進行提問&#xff0c;內容如下&#xff1a; 請生成一個包含以下功能的可運行移動端打臺球小游戲H5文件&#xff1a; 要求 可以重新開始游戲 可以暫停游戲 有白球和其他顏色的球&am…

webpack使用詳細步驟

項目描述 本項目 webpack 的基本使用。 webpack 官方&#xff1a;https://webpack.docschina.org/concepts/ Element-plus 官方&#xff1a;https://element-plus.sxtxhy.com/zh-CN/ Vue3 官方&#xff1a;https://cn.vuejs.org/ 項目組成明細 每個步驟完成后重新執行 npm run …

【STM32實物】基于STM32的太陽能充電寶設計

基于STM32的太陽能充電寶設計 演示視頻: 基于STM32的太陽能充電寶設計 硬件組成: 系統硬件包括主控 STM32F103C8T6、0.96 OLED 顯示屏、蜂鳴器、電源自鎖開關、溫度傳感器 DS18B20、繼電器、5 V DC 升壓模塊 、TB4056、18650鋰電池、9 V太陽能板、穩壓降壓 5 V三極管。 功能…

【記一次】AI微調訓練步數計算方式

llama微調訓練步數計算方式,以下數據為假設 一、關鍵參數解析 總樣本數&#xff1a;Num examples 1,047 表示訓練數據集包含 1,047 個樣本。 訓練輪數&#xff1a;Num Epochs 300 表示整個訓練集將被遍歷 300 次。 總批次大小&#xff1a;Total train batch size 80 表示…

python-selenium 爬蟲 由易到難

本質 python第三方庫 selenium 控制 瀏覽器驅動 瀏覽器驅動控制瀏覽器 推薦 edge 瀏覽器驅動&#xff08;不容易遇到版本或者兼容性的問題&#xff09; 驅動下載網址&#xff1a;鏈接: link 1、實戰1 &#xff08;1&#xff09;安裝 selenium 庫 pip install selenium&#…

yaffs

YAFFS&#xff08;Yet Another Flash File System&#xff09;是專為NAND閃存設計的日志結構文件系統&#xff0c;其核心原理圍繞NAND閃存的特性優化數據管理。以下是其關鍵原理的詳細說明&#xff1a; 1. NAND閃存適配 寫入限制&#xff1a;NAND閃存需按頁寫入&#xff08;通…

git的底層原理

git的底層原理 三段話總結git&#xff0c; 1. 工作原理&#xff1a;git管理是一個DAG有向無環圖&#xff0c;HEAD指針指向branch或直接指向commit&#xff0c;branch指向commit&#xff0c;commit指向tree&#xff0c;tree指向別的tree或直接指向blob。 2. git所管理的一個目錄…