IP多播实现

//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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值