⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 udp.c

📁 C语言源码
💻 C
📖 第 1 页 / 共 2 页
字号:
    }
    /*发送完毕后关闭套接字、释放占用资源*/
    closesocket(socketBro);
    WSACleanup();
}

/*广播消息接收函数*/
void broadcastRec()
{   
    BOOL optval = TRUE;
    int addrBroLen;
    char buf[256];
    DWORD i=0;
    /*该地址用来绑定套接字*/
    addrRec.sin_family=AF_INET;
    addrRec.sin_addr.s_addr=0;
    addrRec.sin_port=htons(bPort);

    /*该地址用来接收网路上广播的消息*/
    addrBro.sin_family=AF_INET;
    addrBro.sin_addr.s_addr=bcastAddr;
    addrBro.sin_port=htons(bPort);
    
    addrBroLen=sizeof(addrBro);
    //创建UDP套接字
    socketRec=socket(AF_INET,SOCK_DGRAM,0);
    /*如果创建失败*/
    if(socketRec==INVALID_SOCKET)
    {
        printf("Create socket error:%d",WSAGetLastError());
        WSACleanup();
        return;
    }

    /*设置该套接字为可重用类型*/
    if(setsockopt(socketRec,SOL_SOCKET,SO_REUSEADDR,(char FAR *)&optval,
                                                			sizeof(optval))==SOCKET_ERROR)
    /*如果设置失败*/
    {
        printf("setsockopt failed:%d",WSAGetLastError());
        closesocket(socketRec);
        WSACleanup();
        return;
    }
    /*绑定套接字和地址*/
    if(bind(socketRec,(struct sockaddr *)&addrRec,
                                sizeof(struct sockaddr_in))==SOCKET_ERROR)
    /*如果绑定失败*/
    {
        printf("bind failed with: %d\n", WSAGetLastError());
        closesocket(socketRec);
        WSACleanup();
        return ;
    }
    /*从广播地址接收消息*/
    while(i<bCount)
    {
        recvfrom(socketRec,buf,256,0,(struct sockaddr FAR *)&addrBro,(int FAR *)&addrBroLen);
        /*延迟2秒钟*/
        Sleep(2000);
        /*输出接收到缓冲区的消息*/
        printf("%s\n",buf);
        /*情况缓冲区*/
        ZeroMemory(buf,256);
        i++;
    }
    /*接收完毕后关闭套接字、释放占用资源*/
    closesocket(socketRec);
    WSACleanup();
}

/*多播控制函数*/
void mulControl()
{
    int optval; 
    /*创建UDP套接字,用于多播*/
    if ((socketMul = WSASocket(AF_INET, SOCK_DGRAM, 0, NULL, 0,
                  WSA_FLAG_MULTIPOINT_C_LEAF 
                  | WSA_FLAG_MULTIPOINT_D_LEAF 
                  | WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET)
    {
        printf("socket failed with: %d\n", WSAGetLastError());
        WSACleanup();
        return ;
    }
    
    /*设置本地接口地址*/
    addrLocal.sin_family = AF_INET;
    addrLocal.sin_port = htons(mPort);
    addrLocal.sin_addr.s_addr = dwInterface;
    
    /*将UDP套接字绑定到本地地址上*/
    if (bind(socketMul, (struct sockaddr *)&addrLocal, 
                                    sizeof(addrLocal)) == SOCKET_ERROR)
    /*如果绑定失败*/
    {
        printf("bind failed with: %d\n", WSAGetLastError());
        closesocket(socketMul);
        WSACleanup();
        return ;
    }

    /*设置多播地址各个选项*/
    addrMul.sin_family      = AF_INET;
    addrMul.sin_port        = htons(mPort);
    addrMul.sin_addr.s_addr = dwMulticastGroup;

    /*重新设置TTL值*/
    optval = 8;
    /*设置多播数据的TTL(存在时间)值。默认情况下,TTL值是1*/
    if (setsockopt(socketMul, IPPROTO_IP, IP_MULTICAST_TTL, 
        (char *)&optval, sizeof(int)) == SOCKET_ERROR)
    /*如果设置失败*/
    {
        printf("setsockopt(IP_MULTICAST_TTL) failed: %d\n",WSAGetLastError());
        closesocket(socketMul);
        WSACleanup();
        return ;
    }

    /*如果指定了返还选项*/
    if (bLoopBack)
    {
        /*设置返还选项为假,禁止将发送的数据返还给本地接口*/
        optval = 0;
        if (setsockopt(socketMul, IPPROTO_IP, IP_MULTICAST_LOOP,
            (char *)&optval, sizeof(optval)) == SOCKET_ERROR)
        /*如果设置失败*/
    	{
            printf("setsockopt(IP_MULTICAST_LOOP) failed: %d\n",
                WSAGetLastError());
            closesocket(socketMul);
            WSACleanup();
            return ;
        }
    }
    
    /*加入多播组*/
    if ((sockJoin = WSAJoinLeaf(socketMul, (SOCKADDR *)&addrMul, 
                             sizeof(addrMul), NULL, NULL, NULL, NULL, 
                             JL_BOTH)) == INVALID_SOCKET)
    /*如果加入不成功*/
    {
        printf("WSAJoinLeaf() failed: %d\n", WSAGetLastError());
        closesocket(socketMul);
        WSACleanup();
        return ;
    }
}

/*多播消息发送函数*/
void multicastSend()
{
    
    TCHAR  sendbuf[BUFSIZE];
    DWORD i;
    int ret;

    mulControl();
    /*发送mCount条消息*/
    for(i = 0; i < mCount; i++)
    {
        /*将待发送的消息写入发送缓冲区*/
        sprintf(sendbuf, "server 1: This is a test: %d", i);
        ret=sendto(socketMul, (char *)sendbuf, strlen(sendbuf), 0,
                (struct sockaddr *)&addrMul, sizeof(addrMul));
        /*如果发送失败*/
        if(ret==SOCKET_ERROR)
        {
            printf("sendto failed with: %d\n",WSAGetLastError());
            closesocket(sockJoin);
            closesocket(socketMul);
            WSACleanup();
            return ;
        }
        /*如果发送成功*/
        else
            printf("Send message %d\n",i);
         Sleep(500);
     }
    /*关闭套接字、释放占用资源*/
    closesocket(socketMul);
    WSACleanup();
}

/*多播消息接收函数*/
void multicastRec()
{
    DWORD i;
    struct sockaddr_in  from;
    TCHAR recvbuf[BUFSIZE];
    int ret;
    int len = sizeof(struct sockaddr_in);

    mulControl();
    /*接收mCount条消息*/
    for(i = 0; i < mCount; i++)
    {
        /*将接收的消息写入接收缓冲区*/
        if ((ret = recvfrom(socketMul, recvbuf, BUFSIZE, 0,
                (struct sockaddr *)&from, &len)) == SOCKET_ERROR)
        /*如果接收不成功*/
    	{
            printf("recvfrom failed with: %d\n",WSAGetLastError());
            closesocket(sockJoin);
            closesocket(socketMul);
            WSACleanup();
             return ;
        }
        /*接收成功,输出接收的消息*/
        recvbuf[ret] = 0;
        printf("RECV: '%s' from <%s>\n", recvbuf,inet_ntoa(from.sin_addr));
     }
    /*关闭套接字、释放占用资源*/
    closesocket(socketMul);
    WSACleanup();
}

/*主函数*/
int main(int argc, char **argv)
{
    WSADATA wsd;

    initial();
    GetArgments(argc, argv);

    /*初始化Winsock*/
    if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)
    {
        printf("WSAStartup() failed\n");
        return -1;
    }

    /*如果是执行广播程序*/
    if(broadFlag)
    {
        /*以发送者身份发送消息*/
        if(broadSendFlag)
    	{
            broadcastSend();
            return 0;
    	}
        /*以接收者身份接收消息*/
        else
    	{
            broadcastRec();
            return 0;
    	}
    }

    /*如果是执行多播程序*/
    if(multiFlag)
    {
        /*以发送者身份发送消息*/
        if(multiSendFlag) 
    	{
            multicastSend();
            return 0;
        }
        /*以接收者身份接收消息*/
        else    
    	{
            multicastRec();
            return 0;
    	}
    }
    return 0;
}




⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -