当前位置: 首页> 教育> 大学 > UDP通信

UDP通信

时间:2025/7/11 18:13:05来源:https://blog.csdn.net/weixin_43739167/article/details/139243167 浏览次数:0次

UDP通信

夜把花儿悄悄的开放了,却让百日去领受赞美 ——泰戈尔

详细介绍UDP通信中单播、多播、组播和广播的异同

UDP(User Datagram Protocol)是一种无连接的、简单的传输层协议,常用于快速传输数据,适用于实时性要求高的应用。在UDP通信中,单播、多播、组播和广播是四种不同的数据传输方式,它们各自具有特定的用途和特点。

单播(Unicast):

  • 定义:单播是一种点对点的通信方式,数据从一个发送方传输到一个特定的接收方
  • 特点:单播通信是一对一的通信,数据只发送给一个确定的目标地址。
  • 应用场景:适用于需要将数据准确传输给特定目标的场景,例如网页请求、文件传输等。

多播(Multicast):

  • 定义:多播是一种一对多的通信方式,数据从一个发送方传输到多个确定的接收方
  • 特点:多播通信可以同时发送数据给多个接收方,但这些接收方都必须加入到特定的多播组中。
  • 应用场景:适用于需要将数据同时传输给多个特定接收方的场景,例如视频直播、在线游戏等。

组播(Anycast):

  • 定义:组播是一种一对最近的通信方式,数据从一个发送方传输到一组提供相同服务的接收方中的任意一个
  • 特点:组播通信将数据发送到一组接收方中的最近的一个,通常用于服务寻址,选择最近的接收方处理请求。
  • 应用场景:适用于需要向多个地理位置分布的服务器发送数据,并由最近的服务器处理请求的场景,例如域名系统(DNS)查询。

广播(Broadcast):

  • 定义:广播是一种一对全部的通信方式,数据从一个发送方传输到同一网络中的所有设备
  • 特点:广播通信将数据发送到同一网络中的所有设备,所有设备都能够接收到数据。
  • 应用场景:适用于需要向同一局域网中的所有设备发送数据的场景,例如网络发现、ARP(地址解析协议)请求等。

异同点总结:

  • 共同点:单播、多播、组播和广播都是UDP通信中常用的数据传输方式。
  • 不同点它们之间的主要区别在于目标接收方的数量和确定性,以及数据传输的范围和方式

总结

  • 广播:老师:所有人出去跑操

  • 组播:老师:第一排出去扫地

  • 多播:老师:1号、2号、3号,你们仨给我站起来

  • 单播:老师:4号你来回答下这个问题

总的来说,选择合适的数据传输方式取决于通信需求和网络环境,单播、多播、组播和广播各有其适用的场景和优势。

通过程序区分UDP通信的单播、组播、多播和广播的异同

单播

以下是一个简单的示例程序,用于在Linux上实现UDP单播通信。该程序包括一个服务器和一个客户端,服务器接收来自客户端的消息并将其打印出来。

单播服务器代码(unimsg_server.c):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>#define PORT 12345int main() {int sockfd;struct sockaddr_in servaddr, cliaddr;char buffer[1024];// 创建UDP套接字if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {perror("socket creation failed");exit(EXIT_FAILURE);}memset(&servaddr, 0, sizeof(servaddr));memset(&cliaddr, 0, sizeof(cliaddr));// 绑定服务器地址servaddr.sin_family = AF_INET;servaddr.sin_addr.s_addr = INADDR_ANY;servaddr.sin_port = htons(PORT);if (bind(sockfd, (const struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) {perror("bind failed");close(sockfd);exit(EXIT_FAILURE);}printf("Server is listening on port %d...\n", PORT);// 循环接收数据while (1) {socklen_t len = sizeof(cliaddr);int nbytes = recvfrom(sockfd, buffer, sizeof(buffer), 0, (struct sockaddr *)&cliaddr, &len);if (nbytes < 0) {perror("recvfrom failed");close(sockfd);exit(EXIT_FAILURE);}buffer[nbytes] = '\0';printf("Received message from client: %s\n", buffer);}close(sockfd);return 0;
}

单播客户端代码(unimsg_client.c):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>#define SERVER_IP "127.0.0.1"
#define PORT 12345int main() {int sockfd;struct sockaddr_in servaddr;char buffer[1024];// 创建UDP套接字if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {perror("socket creation failed");exit(EXIT_FAILURE);}memset(&servaddr, 0, sizeof(servaddr));// 服务器地址配置servaddr.sin_family = AF_INET;servaddr.sin_port = htons(PORT);if (inet_pton(AF_INET, SERVER_IP, &servaddr.sin_addr) <= 0) {perror("Invalid address/ Address not supported");close(sockfd);exit(EXIT_FAILURE);}// 从标准输入读取消息并发送到服务器printf("Enter message to send to server:\n");fgets(buffer, sizeof(buffer), stdin);sendto(sockfd, buffer, strlen(buffer), 0, (const struct sockaddr *)&servaddr, sizeof(servaddr));printf("Message sent to server\n");close(sockfd);return 0;
}

使用方法:

  1. 将上述代码分别保存到 unimsg_server.cunimsg_client.c 文件中。
  2. 在终端中编译服务器代码:gcc unimsg_server.c -o unimsg_server
  3. 在另一个终端中编译客户端代码:gcc unimsg_client.c -o unimsg_client
  4. 在第一个终端中运行服务器:./unimsg_server
  5. 在第二个终端中运行客户端:./unimsg_client

您可以在客户端终端中输入消息,然后在服务器终端中看到该消息被接收并打印出来。这就完成了一个简单的UDP单播通信示例。

多播

以下是一个简单的示例程序,用于在Linux上实现UDP多播通信。该程序包括一个多播服务器和一个多播客户端,服务器发送消息到组播地址,客户端接收来自服务器的消息。

多播服务器代码(multicast_server.c):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>#define MULTICAST_GROUP "225.0.0.37"
#define PORT 12345int main() {int sockfd;struct sockaddr_in servaddr;char buffer[1024];int nbytes;// 创建UDP套接字if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {perror("socket creation failed");exit(EXIT_FAILURE);}memset(&servaddr, 0, sizeof(servaddr));// 设置服务器地址servaddr.sin_family = AF_INET;servaddr.sin_addr.s_addr = inet_addr(MULTICAST_GROUP);servaddr.sin_port = htons(PORT);// 循环发送数据while (1) {printf("Enter message to multicast:\n");fgets(buffer, sizeof(buffer), stdin);nbytes = sendto(sockfd, buffer, strlen(buffer), 0, (const struct sockaddr *)&servaddr, sizeof(servaddr));if (nbytes < 0) {perror("sendto failed");close(sockfd);exit(EXIT_FAILURE);}}close(sockfd);return 0;
}

多播客户端代码(multicast_client.c):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>#define MULTICAST_GROUP "225.0.0.37"
#define PORT 12345int main() {int sockfd;struct sockaddr_in servaddr;char buffer[1024];// 创建UDP套接字if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {perror("socket creation failed");exit(EXIT_FAILURE);}memset(&servaddr, 0, sizeof(servaddr));// 设置服务器地址servaddr.sin_family = AF_INET;servaddr.sin_addr.s_addr = inet_addr(MULTICAST_GROUP);servaddr.sin_port = htons(PORT);// 加入多播组struct ip_mreq mreq;mreq.imr_multiaddr.s_addr = inet_addr(MULTICAST_GROUP);mreq.imr_interface.s_addr = htonl(INADDR_ANY);if (setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) {perror("setsockopt");close(sockfd);exit(EXIT_FAILURE);}// 循环接收数据while (1) {int nbytes = recvfrom(sockfd, buffer, sizeof(buffer), 0, NULL, NULL);if (nbytes < 0) {perror("recvfrom failed");close(sockfd);exit(EXIT_FAILURE);}buffer[nbytes] = '\0';printf("Received message from server: %s\n", buffer);}close(sockfd);return 0;
}

使用方法:

  1. 将上述代码分别保存到 multicast_server.cmulticast_client.c 文件中。
  2. 在终端中编译服务器代码:gcc multicast_server.c -o multicast_server
  3. 在另一个终端中编译客户端代码:gcc multicast_client.c -o multicast_client
  4. 在第一个终端中运行服务器:./multicast_server
  5. 在第二个终端中运行客户端:./multicast_client

您可以在服务器终端中输入消息,然后在客户端终端中看到该消息被接收并打印出来。这就完成了一个简单的UDP多播通信示例。

组播

以下是一个简单的示例程序,用于在Linux上实现UDP组播通信。该程序包括一个组播服务器和一个组播客户端,服务器发送消息到组播地址,客户端接收来自服务器的消息。

组播服务器代码(groupcast_server.c):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>#define GROUPCAST_GROUP "225.0.0.37"
#define PORT 12345int main() {int sockfd;struct sockaddr_in servaddr;char buffer[1024];int nbytes;// 创建UDP套接字if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {perror("socket creation failed");exit(EXIT_FAILURE);}memset(&servaddr, 0, sizeof(servaddr));// 设置服务器地址servaddr.sin_family = AF_INET;servaddr.sin_addr.s_addr = inet_addr(GROUPCAST_GROUP);servaddr.sin_port = htons(PORT);// 循环发送数据while (1) {printf("Enter message to groupcast:\n");fgets(buffer, sizeof(buffer), stdin);nbytes = sendto(sockfd, buffer, strlen(buffer), 0, (const struct sockaddr *)&servaddr, sizeof(servaddr));if (nbytes < 0) {perror("sendto failed");close(sockfd);exit(EXIT_FAILURE);}}close(sockfd);return 0;
}

组播客户端代码(groupcast_client.c):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>#define GROUPCAST_GROUP "225.0.0.37"
#define PORT 12345int main() {int sockfd;struct sockaddr_in servaddr;char buffer[1024];// 创建UDP套接字if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {perror("socket creation failed");exit(EXIT_FAILURE);}memset(&servaddr, 0, sizeof(servaddr));// 设置服务器地址servaddr.sin_family = AF_INET;servaddr.sin_addr.s_addr = inet_addr(GROUPCAST_GROUP);servaddr.sin_port = htons(PORT);// 绑定客户端地址(可选)struct sockaddr_in cliaddr;memset(&cliaddr, 0, sizeof(cliaddr));cliaddr.sin_family = AF_INET;cliaddr.sin_addr.s_addr = htonl(INADDR_ANY);cliaddr.sin_port = htons(0);if (bind(sockfd, (const struct sockaddr *)&cliaddr, sizeof(cliaddr)) < 0) {perror("bind failed");close(sockfd);exit(EXIT_FAILURE);}// 循环接收数据while (1) {int nbytes = recvfrom(sockfd, buffer, sizeof(buffer), 0, NULL, NULL);if (nbytes < 0) {perror("recvfrom failed");close(sockfd);exit(EXIT_FAILURE);}buffer[nbytes] = '\0';printf("Received message from server: %s\n", buffer);}close(sockfd);return 0;
}

使用方法:

  1. 将上述代码分别保存到 groupcast_server.cgroupcast_client.c 文件中。
  2. 在终端中编译服务器代码:gcc groupcast_server.c -o groupcast_server
  3. 在另一个终端中编译客户端代码:gcc groupcast_client.c -o groupcast_client
  4. 在第一个终端中运行服务器:./groupcast_server
  5. 在第二个终端中运行客户端:./groupcast_client

您可以在服务器终端中输入消息,然后在客户端终端中看到该消息被接收并打印出来。这就完成了一个简单的UDP组播通信示例。

广播

以下是一个简单的示例程序,用于在Linux上实现UDP广播通信。该程序包括一个广播服务器和一个广播客户端,服务器发送消息到广播地址,客户端接收来自服务器的消息。

广播服务器代码(broadcast_server.c):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>#define BROADCAST_IP "192.168.0.255"
#define PORT 12345int main() {int sockfd;struct sockaddr_in servaddr;char buffer[1024];int nbytes;// 创建UDP套接字if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {perror("socket creation failed");exit(EXIT_FAILURE);}memset(&servaddr, 0, sizeof(servaddr));// 设置广播地址servaddr.sin_family = AF_INET;servaddr.sin_addr.s_addr = inet_addr(BROADCAST_IP);servaddr.sin_port = htons(PORT);// 设置广播权限int broadcast_enable = 1;if (setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &broadcast_enable, sizeof(broadcast_enable)) < 0) {perror("setsockopt broadcast failed");close(sockfd);exit(EXIT_FAILURE);}// 循环发送数据while (1) {printf("Enter message to broadcast:\n");fgets(buffer, sizeof(buffer), stdin);nbytes = sendto(sockfd, buffer, strlen(buffer), 0, (const struct sockaddr *)&servaddr, sizeof(servaddr));if (nbytes < 0) {perror("sendto failed");close(sockfd);exit(EXIT_FAILURE);}}close(sockfd);return 0;
}

广播客户端代码(broadcast_client.c):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>#define PORT 12345int main() {int sockfd;struct sockaddr_in servaddr, cliaddr;char buffer[1024];// 创建UDP套接字if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {perror("socket creation failed");exit(EXIT_FAILURE);}memset(&servaddr, 0, sizeof(servaddr));memset(&cliaddr, 0, sizeof(cliaddr));// 设置服务器地址servaddr.sin_family = AF_INET;servaddr.sin_addr.s_addr = INADDR_ANY;servaddr.sin_port = htons(PORT);// 绑定客户端地址cliaddr.sin_family = AF_INET;cliaddr.sin_addr.s_addr = htonl(INADDR_ANY);cliaddr.sin_port = htons(0);if (bind(sockfd, (const struct sockaddr *)&cliaddr, sizeof(cliaddr)) < 0) {perror("bind failed");close(sockfd);exit(EXIT_FAILURE);}// 循环接收数据while (1) {int nbytes = recvfrom(sockfd, buffer, sizeof(buffer), 0, NULL, NULL);if (nbytes < 0) {perror("recvfrom failed");close(sockfd);exit(EXIT_FAILURE);}buffer[nbytes] = '\0';printf("Received message from server: %s\n", buffer);}close(sockfd);return 0;
}

使用方法:

  1. 将上述代码分别保存到 broadcast_server.cbroadcast_client.c 文件中。
  2. 在终端中编译服务器代码:gcc broadcast_server.c -o broadcast_server
  3. 在另一个终端中编译客户端代码:gcc broadcast_client.c -o broadcast_client
  4. 在第一个终端中运行服务器:./broadcast_server
  5. 在第二个终端中运行客户端:./broadcast_client

您可以在服务器终端中输入消息,然后在客户端终端中看到该消息被接收并打印出来。这就完成了一个简单的UDP广播通信示例。

设置组播路由

route add -net 224.0.0.0 netmask 224.0.0.0 eth0 命令在Linux系统中用于添加一条网络路由,这条路由专门处理IPv4组播地址。下面是对命令的详细解释:

命令的作用

该命令的作用是添加一条路由,以便通过指定的网络接口(例如eth0)来处理发送到组播地址范围(224.0.0.0到239.255.255.255)的流量。组播是一种网络通信方法,允许数据从一个源发送到多个特定的接收者。

参数的意义

1. route

route命令用于查看和操作IP路由表。路由表决定了网络流量通过哪条路径发送到目的地。

2. add

add参数指定要添加一条新路由。

3. -net 224.0.0.0

-net参数指定一个网络地址。在这里,224.0.0.0表示组播地址的起始地址。IPv4组播地址范围是从224.0.0.0到239.255.255.255,这些地址专用于多播传输。

4. netmask 224.0.0.0

netmask参数指定了网络掩码。在这里,224.0.0.0的网络掩码用于覆盖组播地址范围。这个掩码表示前三位固定(即二进制1110),适用于组播地址范围:

  • 224.0.0.0在二进制中表示为 1110 0000.0000 0000.0000 0000.0000 0000
  • 掩码224.0.0.0在二进制中表示为 1110 0000.0000 0000.0000 0000.0000 0000

这意味着只要IP地址前3位是111,这条路由规则就适用,这恰好覆盖了组播地址范围。

5. eth0

eth0参数指定了网络接口。这表示所有匹配组播地址的流量都会通过eth0接口传输。eth0通常是系统中第一个以太网接口的名称。

总结

  • route add -net 224.0.0.0:告诉系统要添加一个针对224.0.0.0网络的路由。
  • netmask 224.0.0.0:指定网络掩码,表明该路由适用于所有224.0.0.0239.255.255.255之间的组播地址。
  • eth0:指定了通过eth0网络接口来处理这些组播地址的数据流量。

应用场景

这种配置常用于启用组播应用程序和服务,例如视频流传输、网络会议、在线游戏和其他需要多播通信的应用。通过添加这条路由,系统能够正确处理组播流量,确保数据能够在网络中的多个接收者之间有效传输。

验证路由

可以使用route -nip route命令来查看路由表,确认新添加的路由是否正确应用。

route -n
# 或
ip route show

希望这个详细解释能帮助你理解route add -net 224.0.0.0 netmask 224.0.0.0 eth0命令的作用和每个参数的意义。

关键字:UDP通信

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: