用多播和IO复用实现命令行群聊

来源:互联网 发布:昆山华道数据有限公司 编辑:程序博客网 时间:2024/06/06 03:39
#include <poll.h>#include <stdio.h>#include <string.h>#include <errno.h>#include <sys/types.h>#include <sys/socket.h>#include <arpa/inet.h>#include <netinet/in.h>#define MULTI_GROUP "224.1.1.1"#define PORT 8000int main(int argc, char * argv[]){int ret = -1;int reuse = 1;char input_buf[128] = {0};char recv_buf[128]  = {0};struct ip_mreq mgroup;struct sockaddr_in local;struct sockaddr_in multi;struct sockaddr_in sender; socklen_t senderlen;struct pollfd fdset[2]; int sockfd;memset(&local, 0, sizeof(local));memset(&multi, 0, sizeof(multi));memset(&sender, 0, sizeof(sender));senderlen  = sizeof( sender );local.sin_family = AF_INET;local.sin_port   = htons(PORT);local.sin_addr.s_addr = INADDR_ANY; multi.sin_family = AF_INET;multi.sin_port   = htons(PORT);multi.sin_addr.s_addr = inet_addr(MULTI_GROUP);mgroup.imr_multiaddr.s_addr = inet_addr(MULTI_GROUP);mgroup.imr_interface.s_addr = INADDR_ANY;sockfd = socket(AF_INET, SOCK_DGRAM, 0);if( sockfd < 0 ){perror("socket");return -1;}ret = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR,&reuse, sizeof(reuse));if( ret < 0 ){perror("setsockopt(REUSEADDR)");close(sockfd);return -1;}ret = setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mgroup, sizeof(mgroup));if( ret < 0 ){perror("setsockopt(ADD_MEMBERSHIP)");close(sockfd);return -1;}ret = bind(sockfd, (struct sockaddr*)&local, sizeof(local));if( ret < 0 ){perror("bind");close(sockfd);return -1;}while(1){fdset[0].fd = 0; // stdin,user input from keyboardfdset[0].events = POLLIN;fdset[1].fd = sockfd;fdset[1].events = POLLIN;poll(fdset, 2, -1);if( fdset[0].revents & POLLIN ){fgets( input_buf, sizeof(input_buf), stdin);sendto(sockfd,input_buf, strlen(input_buf)+1,0,(struct sockaddr*)&multi, sizeof(multi) );}if( fdset[1].revents & POLLIN ){ret = recvfrom(sockfd, recv_buf, sizeof(recv_buf),0,(struct sockaddr*)&sender, &senderlen);if( ret > 0 && strcmp(input_buf, recv_buf))printf("IP:%s >> %s\n", inet_ntoa(sender.sin_addr),recv_buf);}}close(sockfd);return 0;}

原创粉丝点击