多播基礎知識:
普通IP通訊是在一個寄件者和一個接收者之間進行的,我們常把它稱為點對點的通訊,但對於有些應用,這種點對點的通訊模式不能有效地滿足實際應用的需求。例如:一個數字電話會議系統由多個會場組成,當在其中一個會場的參會人發言時,要求其它會場都能即時的得到此發言的內容,這是一個典型的一對多的通訊應用,通常把這種一對多的通訊稱為多播通訊。採用多播通訊技術,不僅可以實現一個寄件者和多個接收者之間進行通訊的功能,而且可以有效減輕網路通訊的負擔,避免資源的無謂浪費。
廣播也是一種實現一對多資料通訊的模式,但廣播與多播在實現方式上有所不同。
廣播是將資料從一個工作站發出,區域網路內的其他所有工作站都能收到它。這一特徵適用於無連線協定,因為LAN上的所有機器都可獲得並處理廣播訊息。使用廣播訊息的不利之處是每台機器都必須對該訊息進行處理。
多播通訊則不同,資料從一個工作站發出後,如果在其它LAN上的機器上面啟動並執行進程表示對這些資料“有興趣”,多播資料才會制給它們。
多播位址範圍:224.0.0.0到239.255.255.255,但是很多是不能用的,例如:224.0.0.0是保留地址,具體的請自己查閱相關文檔。。
要實現接受到多播訊息,那麼你就必須加入多播組,那麼這個組內的成員發送的多播訊息,你才能接受的到。WSAJoinLeaf就是實現這個功能的。
實現:接受者:
#include <iostream>#include <string>#include <winsock2.h>#pragma comment(lib,"ws2_32.lib")using namespace std;#define bufferSize 1024void main(){WORD wVersionRequested;WSADATA wsaData;int err;wVersionRequested = MAKEWORD( 2, 2 );err = WSAStartup( wVersionRequested, &wsaData );if ( err != 0 ) { return;}if ( LOBYTE( wsaData.wVersion ) != 2 ||HIBYTE( wsaData.wVersion ) != 2 ) {WSACleanup( );return; }SOCKET socket;if((socket=WSASocket(AF_INET,SOCK_DGRAM,0,NULL,0,WSA_FLAG_MULTIPOINT_C_LEAF|WSA_FLAG_MULTIPOINT_D_LEAF|WSA_FLAG_OVERLAPPED))==INVALID_SOCKET){cout<<"socket failed with: "<<WSAGetLastError()<<endl;WSACleanup();return;}sockaddr_in localAddress;localAddress.sin_family=AF_INET;localAddress.sin_port=htons(2500);localAddress.sin_addr.S_un.S_addr=INADDR_ANY;int length=sizeof(localAddress);if(bind(socket,(sockaddr*)&localAddress,length)==SOCKET_ERROR){cout<<" 綁定失敗:"<<WSAGetLastError()<<endl;closesocket(socket);WSACleanup();return;}sockaddr_in remoteAddress;remoteAddress.sin_family=AF_INET;remoteAddress.sin_port=htons(2500);remoteAddress.sin_addr.S_un.S_addr=inet_addr("233.0.0.1");SOCKET socket_join;if((socket_join=WSAJoinLeaf(socket,(const sockaddr*)&remoteAddress,sizeof(remoteAddress),NULL,NULL,NULL,NULL,JL_BOTH))==SOCKET_ERROR){cout<<"wsaJoinLeaf() failed: "<<WSAGetLastError()<<endl;closesocket(socket);WSACleanup();return;}char receiverBuf[bufferSize];sockaddr_in fromAddress;int len=sizeof(fromAddress);while (1){int retCount;if((retCount=recvfrom(socket,receiverBuf,bufferSize,0,(sockaddr*)&fromAddress,&len))==SOCKET_ERROR){cout<<"recvfrom failed with:"<<WSAGetLastError()<<endl;closesocket(socket_join);closesocket(socket);WSACleanup();return;}if (strcmp(receiverBuf,"quit")==0)break;else{receiverBuf[retCount]='\0';cout<<"data:"<<receiverBuf<<'\n'<<"from: "<<inet_ntoa(fromAddress.sin_addr)<<endl;}}closesocket(socket_join);closesocket(socket);WSACleanup();return;}
載入winsock庫版本等資訊,初始化----->綁定到自己的IP連接埠------>加入多播組------>接受資料..
寄件者:
#include <iostream>#include <string>#include <winsock2.h>#pragma comment(lib,"ws2_32.lib")using namespace std;#define bufferSize 1024void main(){WORD wVersionRequested;WSADATA wsaData;int err;wVersionRequested = MAKEWORD( 2, 2 );err = WSAStartup( wVersionRequested, &wsaData );if ( err != 0 ) { return;}if ( LOBYTE( wsaData.wVersion ) != 2 ||HIBYTE( wsaData.wVersion ) != 2 ) {WSACleanup( );return; }SOCKET socket;if((socket=WSASocket(AF_INET,SOCK_DGRAM,0,NULL,0,WSA_FLAG_MULTIPOINT_C_LEAF|WSA_FLAG_MULTIPOINT_D_LEAF|WSA_FLAG_OVERLAPPED))==INVALID_SOCKET){cout<<"socket failed with: "<<WSAGetLastError()<<endl;WSACleanup();return;}sockaddr_in remoteAddress;remoteAddress.sin_family=AF_INET;remoteAddress.sin_port=htons(2500);remoteAddress.sin_addr.S_un.S_addr=inet_addr("233.0.0.1");SOCKET socket_join;if((socket_join=WSAJoinLeaf(socket,(const sockaddr*)&remoteAddress,sizeof(remoteAddress),NULL,NULL,NULL,NULL,JL_BOTH))==SOCKET_ERROR){cout<<"wsaJoinLeaf() failed: "<<WSAGetLastError()<<endl;closesocket(socket);WSACleanup();return;}char sendBuffer[bufferSize];while(1){cout<<"Send: ";cin>>sendBuffer;if((sendto(socket,sendBuffer,strlen(sendBuffer),0,(sockaddr*)&remoteAddress,sizeof(remoteAddress)))==SOCKET_ERROR){cout<<"Sendto failed with: "<<WSAGetLastError()<<endl;closesocket(socket_join);closesocket(socket);WSACleanup();return;}if(strcmp(sendBuffer,"quit")==0)break;}closesocket(socket);WSACleanup();return;}
由於是參考著網上的例子寫的,目前沒有兩台機器在旁邊,所以不能測試能不能成功發送接受訊息,每次啟動第二個exe就直接消失。。大家自己找兩台測試看看。。