//ip多播的实现
#include<windows.h>
#include <winsock2.h>
#include<ws2tcpip.h>
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<process.h>
#pragma comment(lib, "ws2_32.lib")
//#define MULTICAST_IP "238.238.0.1" //本例使用的多播组IP地址238.238.0.1
#define MULTICAST_PORT 5150 //绑定的本地端口号
#define BUFFERSIZE 1024 //接收数据缓冲大小
using namespace std;
char MULTICAST_IP[255];//本例使用的多播组IP地址
//发送函数
void do_send(void* arg){
SOCKET server = (SOCKET)arg;
char sendline[BUFFERSIZE+1];
// 远端地址
sockaddr_in remote;
memset(&remote, 0, sizeof(remote)); // memset初始化清空remote远端地址
remote.sin_addr.s_addr = inet_addr(MULTICAST_IP); // 本例使用的多播组IP地址
remote.sin_family = AF_INET; // IPv4
remote.sin_port = htons(MULTICAST_PORT); // 5150 绑定的本地端口号
for(;;){
cin.getline(sendline,BUFFERSIZE); // 读取输入数据
if(strncmp(sendline,"QUIT",4)==0) // 判断终止
break;
// 套接字、缓冲区、缓冲区长度、方式标志位、目的地址、地址长度
sendto(server,sendline,strlen(sendline),0,(sockaddr*)(&remote),sizeof(remote));
}
closesocket(server);
}
//接收函数
void do_read(void* arg){
struct sockaddr_in from;
SOCKET server = (SOCKET)arg;
char buf[BUFFERSIZE+1];
int ret;
sockaddr_in client;
int clientLen;
for(;;){//一只读取直到主线程终止
clientLen = sizeof(client);
memset(&client,0,clientLen);
ret=recvfrom(server,buf,BUFFERSIZE,0,(sockaddr*)&from,&clientLen);
if(ret==0)
continue;
else if(ret==SOCKET_ERROR){
if(WSAGetLastError()==WSAEINTR)
break;
cout<<"Error in recvfrom:"<<WSAGetLastError()<<endl;
break;
}
buf[ret] = '\0';
cout<<"IP地址为->"<<inet_ntoa(from.sin_addr)<<"的用户说:"<<buf<<endl;
}
closesocket(server);
}
int main(int argc,char **argv){
cout<<"请输入IP多播地址:"<<endl;
cin>>MULTICAST_IP;
cout<<"开启你的IP多播之旅吧!"<<endl;
WSADATA wsd;
// 本地地址、远程地址
struct sockaddr_in local,remote;
SOCKET sock;
// 完成对Winsock服务的初始化
WSAStartup(MAKEWORD(2,2),&wsd);
sock=WSASocket(AF_INET,SOCK_DGRAM,0,NULL,0,WSA_FLAG_MULTIPOINT_C_LEAF|WSA_FLAG_MULTIPOINT_D_LEAF|WSA_FLAG_OVERLAPPED);
local.sin_family=AF_INET; // IPv4
local.sin_port=htons(MULTICAST_PORT); // 5150 绑定的本地端口号
local.sin_addr.s_addr=INADDR_ANY; // 本机的所有IP
// 将此Socket绑定到本地的一个端口上,为了接收服务器端发送的多播数据
bind(sock,(struct sockaddr*)&local,sizeof(local));
remote.sin_family=AF_INET; // IPv4
remote.sin_port=htons(MULTICAST_PORT); // 5150 绑定的本地端口号
remote.sin_addr.s_addr=inet_addr(MULTICAST_IP); //本例使用的多播组IP地址
// 加入多播组 套接口、远端名称、长度、指针、标志位JL_BOTH既是接收者也是发送者
WSAJoinLeaf(sock,(SOCKADDR*)&remote,sizeof(remote),NULL,NULL,NULL,NULL,JL_BOTH);
// 使用多线程调用读写函数。
HANDLE hHandle[2];
// _beginthread创建一个线程 地址、堆栈大小、线程参数
hHandle[0]=(HANDLE)_beginthread(do_send,0,(void*)sock);
hHandle[1]=(HANDLE)_beginthread(do_read,0,(void*)sock);
// 等待上一个发送状态执行完毕
WaitForSingleObject(hHandle[0],INFINITE);
// 终止winsocket
WSACleanup();
return 0;
}
11-25
1335
“相关推荐”对你有帮助么?
-
非常没帮助
-
没帮助
-
一般
-
有帮助
-
非常有帮助
提交