服务器:
#include<sys/types.h> // 支持套接字地址结构
#include <sys/socket.h> // 提供套接字API
#include <netinet/in.h> // 定义IP地址结构体
#include <string.h> // 提供字符串操作函数
#include <stdio.h> // 提供标准I/O操作函数
#include <arpa/inet.h> // 提供IP地址转换函数
#include <stdlib.h>
#include "string.h"
#include "pthread.h"// udo组播代码
int main(int argc, char *argv[])
{int sockfd = socket(AF_INET, SOCK_DGRAM, 0); // 创建UDP套接字if (sockfd < 0){perror("socket");return -1;}struct ip_mreq mreq; // 定义IP多播结构体mreq.imr_multiaddr.s_addr = inet_addr("224.10.10.10"); // 设置多播组IP地址.mreq.imr_interface.s_addr = INADDR_ANY; // 设置本地接口为任何接口// 加入多播组if (setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0){perror("setsockopt");return -1;}struct sockaddr_in server_addr; // 定义服务器地址结构体memset(&server_addr, 0, sizeof(server_addr)); // 初始化服务器地址结构体server_addr.sin_family = AF_INET; // 设置地址族为IPv4server_addr.sin_addr.s_addr = htonl(INADDR_ANY); // 设置服务器IP地址为任何地址server_addr.sin_port = htons(atoi(argv[1])); // 设置服务器端口号为8000// 绑定套接字到服务器地址if (bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0){perror("bind");return -1;}char buffer[1024]; // 定义缓冲区struct sockaddr_in client_addr; // 定义客户端地址结构体socklen_t client_addr_len = sizeof(client_addr); // 定义客户端地址长度while (1){memset(buffer, 0, sizeof(buffer)); // 清空缓冲区int len = recvfrom(sockfd, buffer, sizeof(buffer), 0, (struct sockaddr *)&client_addr, &client_addr_len); // 接收数据if(strncmp(buffer,"start",5)==0){char buf[1024];snprintf(buf,1024,"%s:%d 上线了",inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port));sendto(sockfd,buf,strlen(buf),0,(struct sockaddr *)&server_addr,client_addr_len);continue;}else if(strncmp(buffer,"end",3)==0){char buf[1024];snprintf(buf,1024,"%s:%d 下线了",inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port));sendto(sockfd,buf,strlen(buf),0,(struct sockaddr *)&server_addr,client_addr_len);continue;}if (len < 0){perror("recvfrom");continue;}buffer[len] = '\0';printf("Received message: %s\n", buffer); // 打印接收到的消息}return 0;
}
客户端:
#include<sys/types.h> // 支持套接字地址结构
#include <sys/socket.h> // 提供套接字API
#include <netinet/in.h> // 定义IP地址结构体
#include <string.h> // 提供字符串操作函数
#include <stdio.h> // 提供标准I/O操作函数
#include <arpa/inet.h> // 提供IP地址转换函数
#include <stdlib.h>
#include "string.h"
#include "pthread.h"
#include "signal.h"int sockfd;
struct sockaddr_in mcast_addr; // 定义组播地址结构体void func(void)
{sendto(sockfd, "end", strlen("end"), 0, (struct sockaddr *)&mcast_addr, sizeof(mcast_addr));exit(0);
}// UDP组播
int main(int argc, char *argv[])
{sockfd = socket(AF_INET, SOCK_DGRAM, 0); // 创建UDP套接字if (sockfd < 0){perror("socket");return -1;}mcast_addr.sin_family = AF_INET; // 设置地址族为IPv4mcast_addr.sin_addr.s_addr = inet_addr("224.10.10.10"); // 设置组播组IP地址mcast_addr.sin_port = htons(atoi(argv[1])); // 设置组播组端口号sendto(sockfd, "start", strlen("start"), 0, (struct sockaddr *)&mcast_addr, sizeof(mcast_addr));signal(SIGINT, (void *)func);// 循环发送数据while (1){char buffer[1024];printf("Enter message to send: ");fgets(buffer, sizeof(buffer), stdin);buffer[strlen(buffer) - 1] = '\0'; // 去掉fgets获取的回车int len = sendto(sockfd, buffer, strlen(buffer), 0, (struct sockaddr *)&mcast_addr, sizeof(mcast_addr));if (len < 0){perror("sendto");continue;}}return 0;
}