SOCKET UDP组播 实例(亲测可行)
区分Server端和Client端:Server端是要监听的。
阻塞式的基于UDP的组播程序代码,在Windows XP上测试通过~
https://www.cnblogs.com/jersey/archive/2011/11/23/2259985.html
客户端Sender.cpp
#include <WINSOCK.H> #include <stdio.h> #define HELLO_PORT 7905 #define HELLO_GROUP "228.4.5.6" #pragma comment(lib, "WSOCK32.lib") int main(int argc, char *argv[]) { WSADATA wsaData; WORD wVersionRequested; wVersionRequested = MAKEWORD(1,1); // Initialize Windows socket library WSAStartup(0x0202, &wsaData); struct sockaddr_in addr; int fd, cnt; char *message="Hello, World!"; /* create what looks like an ordinary UDP socket */ if ((fd=socket(AF_INET,SOCK_DGRAM,0)) < 0) { perror("socket"); exit(1); } /* set up destination address */ memset(&addr,0,sizeof(addr)); addr.sin_family=AF_INET; addr.sin_addr.s_addr=inet_addr(HELLO_GROUP); addr.sin_port=htons(HELLO_PORT); /* now just sendto() our destination! */ while (1) { if (sendto(fd,message, strlen(message), 0, (struct sockaddr *) &addr, sizeof(addr)) < 0) { perror("sendto"); exit(1); } printf("Send %s\n",message); Sleep(1000); } return 0; }
服务器端Receiver.cpp
#include <WINSOCK.H> #include <stdio.h> #define HELLO_PORT 7905 #define HELLO_GROUP "228.4.5.6" #define MSGBUFSIZE 256 #pragma comment(lib, "WSOCK32.lib") int main(int argc, char *argv[]) { WSADATA wsaData; WORD wVersionRequested;// Version wVersionRequested = MAKEWORD(1,1);//Version Info // Initialize Windows socket library WSAStartup(wVersionRequested, &wsaData); struct sockaddr_in addr; int fd, nbytes,addrlen; struct ip_mreq mreq; char msgbuf[MSGBUFSIZE]; u_int yes=1; /*** MODIFICATION TO ORIGINAL */ /* create what looks like an ordinary UDP socket */ if ((fd=socket(AF_INET,SOCK_DGRAM,0)) < 0) { perror("socket"); exit(1); } /**** MODIFICATION TO ORIGINAL */ /* allow multiple sockets to use the same PORT number */ if (setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,(char *)&yes,sizeof(yes)) < 0) { perror("Reusing ADDR failed"); exit(1); } /*** END OF MODIFICATION TO ORIGINAL */ /* set up destination address */ memset(&addr,0,sizeof(addr)); addr.sin_family=AF_INET; addr.sin_addr.s_addr=htonl(INADDR_ANY); /* N.B.: differs from sender */ addr.sin_port=htons(HELLO_PORT); /* bind to receive address */ if (bind(fd,(struct sockaddr *) &addr,sizeof(addr)) < 0) { perror("bind"); exit(1); } /* use setsockopt() to request that the kernel join a multicast group */ mreq.imr_multiaddr.s_addr=inet_addr(HELLO_GROUP); mreq.imr_interface.s_addr=htonl(INADDR_ANY); if (setsockopt(fd,IPPROTO_IP,IP_ADD_MEMBERSHIP,(char *)&mreq,sizeof(mreq)) < 0) { int err=GetLastError(); printf("setsockopt:%d",err); exit(1); } /* now just enter a read-print loop */ while (1) { //ssize_t recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen); addrlen=sizeof(addr); printf("Receiving..."); //if((nbytes=recvfrom(fd,msgbuf,MSGBUFSIZE,0,NULL,NULL))<0) if ((nbytes=recvfrom(fd, msgbuf, MSGBUFSIZE, 0, (struct sockaddr *) &addr, (int *)&addrlen)) < 0) { perror("recvfrom"); exit(1); } msgbuf[nbytes] ='\0'; printf("%s",msgbuf); } return 0; }
通常来讲,客户端是不需要绑定端口号的,而服务器端是需要绑定监听的端口号。其他的其实区别不是很大了,呵呵,从socket通信的角度来看,UDP通信属于帧传输,TCP则是流传输,在帧传输过程中对于消息的次序和到达情况没有需求,所以UDP属于不可靠传输,不需要确认和排序。这样在客户端和服务器端的实现上就没有太大的差别了。
但是客户端其实也可以用bind来绑定端口的,你在Linux下写一个简单的测试程序就知道了,嘿嘿。
服务在连接前监听,客户端主动发起连接,就着点区别。连接上后,两者对等