多播无法正常工作

时间:2016-03-25 08:10:00

标签: c winapi winsock

/ * Listner1.c和Listner2.c * /

#include <io.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>
#include <errno.h>

#include <Ws2tcpip.h>
#include <mswsock.h>

#define u_int32 UINT32

#pragma comment(lib,"ws2_32.lib") //Winsock Library

#define CPORT 12000

int main()
{

    int iResult = 0;
    WSADATA wsaData;
    SOCKET RecvSocket;
    struct sockaddr_in RecvAddr;

    struct ip_mreq mreq;

    char RecvBuf[1024];
    int BufLen = 1024;
    int yesopt = 1;
    struct sockaddr_in SenderAddr;
    int SenderAddrSize = sizeof (SenderAddr);

    //-----------------------------------------------
    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != NO_ERROR) {
        wprintf(L"WSAStartup failed with error %d\n", iResult);
        return 1;
    }
    //-----------------------------------------------
    // Create a receiver socket to receive datagrams
    RecvSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (RecvSocket == INVALID_SOCKET) {
        wprintf(L"socket failed with error %d\n", WSAGetLastError());
        return 1;
    }
    //-----------------------------------------------
    // Bind the socket to any address and the specified port.
    if (setsockopt(RecvSocket,SOL_SOCKET, SO_REUSEADDR ,(char *) &yesopt ,sizeof(yesopt)) < 0) {
       perror("Reusing ADDR failed");
       exit(1);
       }

     memset(&RecvAddr,0,sizeof(RecvAddr));
     RecvAddr.sin_family=AF_INET;
     RecvAddr.sin_port=htons(CPORT);
     RecvAddr.sin_addr.s_addr=inet_addr("192.168.0.104"); 


    RecvBuf[0] = '\0';

    mreq.imr_interface.s_addr = inet_addr("192.168.0.104");
    mreq.imr_multiaddr.s_addr = inet_addr("235.0.0.0");

    iResult = setsockopt(RecvSocket,IPPROTO_IP,IP_ADD_MEMBERSHIP,(char *) &mreq,sizeof(mreq));

    if (iResult < 0) {
      perror("membership");
      exit(1);
    } 

    iResult = bind(RecvSocket, (SOCKADDR *) & RecvAddr, sizeof (RecvAddr));
    if (iResult != 0) {
        wprintf(L"bind failed with error %d\n", WSAGetLastError());
        return 1;
    }
    //-----------------------------------------------

    // Call the recvfrom function to receive datagrams
    // on the bound socket.
    wprintf(L"Receiving datagrams...\n");
    while(1) {
    iResult = recvfrom(RecvSocket,
                       RecvBuf, BufLen, 0, (SOCKADDR *) &RecvAddr, &SenderAddrSize);
    if(iResult <= 0 ) break;

    RecvBuf[iResult] = '\0';
    if (iResult == SOCKET_ERROR) {
        wprintf(L"recvfrom failed with error %d\n", WSAGetLastError());
        break;
    }

    puts(RecvBuf);
    }
    //-----------------------------------------------

    iResult = closesocket(RecvSocket);
    if (iResult == SOCKET_ERROR) {
        wprintf(L"closesocket failed with error %d\n", WSAGetLastError());
        return 1;
    }

    //-----------------------------------------------
    // Clean up and exit.
   // wprintf(L"Exiting.\n");
    WSACleanup();
    return 0;
}

我从上面的代码创建了2个进程...即 listner1.exe和listner2.exe ......

以及以下发送邮件的代码.. Sender.c ...

#include<io.h>
#include<stdio.h>
#include <stdlib.h>
#include <string.h>
#include<winsock2.h>
#include <errno.h>


#include <Ws2tcpip.h>
#include <mswsock.h>

#define u_int32 UINT32

#pragma comment(lib,"ws2_32.lib") //Winsock Library

#define HELLO_PORT 12000
#define HELLO_GROUP "192.168.0.104"

main(int argc, char *argv[])
{
     WSADATA wsa;
     struct sockaddr_in addr;
     int fd;
     char message[2000];
     int opt = 1;
     int iResult = 0;

     strcpy ( message , argv[1] );

    if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
    {
        printf("Failed. Error Code : %d",WSAGetLastError());
        return 1;
    }

     /* 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("192.168.0.104");
     addr.sin_port=htons(HELLO_PORT);


      if (sendto(fd,message,strlen(message),0,(struct sockaddr *) &addr,
             sizeof(addr)) < 0) {
           perror("sendto");
           exit(1);
      }

}

当我在2个不同的命令窗口中运行listner1.exe和listner2.exe时 并运行 Sender.exe&#34;你好&#34; 消息仅传递给单个进程。首先开始的过程 (例如 - 如果listner2.exe在listner1.exe之前启动,则所有消息仅发送到listner2。 如果我退出并重新启动listner2.exe,保持listner1.exe活着,然后 新邮件仅发送到listner1.exe。

我无法找到原因,多播不会发生。

此致 Sadanand

1 个答案:

答案 0 :(得分:0)

在您的服务器中,您必须与多播地址通信:

  /* set up destination address */
     memset(&addr,0,sizeof(addr));
     addr.sin_family=AF_INET;
     addr.sin_addr.s_addr=inet_addr("235.0.0.0");
     addr.sin_port=htons(HELLO_PORT);

      if (sendto(fd,message,strlen(message),0,(struct sockaddr *) &addr,
             sizeof(addr)) < 0) {
           perror("sendto");
           exit(1);
      }

此外,在我的计算机上,在侦听器中,我在多播成员资格之前进行绑定,以使侦听器正常工作。