程序为什么接收不到组播的消息?recvfrom一直不返回

sunnysab 2013-08-22 05:12:46
#include <stdio.h>
#include <winsock2.h>

#pragma comment( lib, "ws2_32.lib")

int main()
{
WSADATA wsadata;
SOCKET Socket, socket;
SOCKADDR_IN from, to;

WSAStartup( 0x0202, &wsadata );

printf("初始化完毕!\n");
Socket = WSASocket( AF_INET, SOCK_DGRAM, 0, NULL, 0, WSA_FLAG_MULTIPOINT_D_LEAF|WSA_FLAG_MULTIPOINT_C_LEAF
|WSA_FLAG_OVERLAPPED);


if( !Socket )
{
printf( "创建socket失败: %d\n", WSAGetLastError() );
return 0;
}
printf("socket建立\n");

from.sin_family = AF_INET;
from.sin_port = htons( 1000 );
from.sin_addr.S_un.S_addr = htonl(INADDR_ANY);

to.sin_family = AF_INET;
to.sin_port = htons( 4804 );
to.sin_addr.S_un.S_addr = inet_addr( "224.40.40.40" );

if( bind( Socket, (SOCKADDR*)&from, sizeof(from) ) == SOCKET_ERROR )
{
printf( "bind失败: %d\n", WSAGetLastError() );
return 0;
}
printf("bind完成\n");

if( ( socket = WSAJoinLeaf( Socket, (SOCKADDR*)&to,sizeof(to),NULL,NULL,NULL,NULL, JL_BOTH)) == SOCKET_ERROR )
{
printf("WSAJoinLeaf()失败: %d\n",WSAGetLastError());
closesocket(Socket);
WSACleanup();
return 0;
}
printf("joinleaf\n");

while( 1 )
{
char recvbuffer[100];
int value = 0;
int len = sizeof(to);

memset( recvbuffer, 0, 100);
value = recvfrom( socket, recvbuffer, 100, 0, (struct sockaddr*)&to, &len);

printf("value = %d\n",value);
printf( "%s\n", recvbuffer );
}

closesocket(Socket);
closesocket(socket);
WSACleanup();
return 0;
}

通过拦包发现,明明有向224.40.40.40:4804发送了数据,可是程序为啥收不到?求指点
...全文
761 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
木头菇 2013-08-23
  • 打赏
  • 举报
回复
引用 12 楼 sunnysab 的回复:
[quote=引用 8 楼 spirit008 的回复:] 把你bind端口和join端口改成一个,另外,ws2的这个joinleaf有毛病,不能用这个socket发单播,组播的话还是用老的方式好一些。 ip_mreq mcast; mcast.imr_interface.S_un.S_addr = INADDR_ANY; mcast.imr_multiaddr.S_un.S_addr = inet_addr("230.0.1.2"); setsockopt(s,IPPROTO_IP,IP_ADD_MEMBERSHIP,(char*)&mcast,sizeof(mcast));
我刚才又看了一下代码,现在总算知道我是哪里错了。 就如您所说,把bind的端口和组播端口改成样的就可以了。 那么如果要发送数据就不用保持一致吧?[/quote] 你只是向组里发数据的话,你都不需要去bind。
sunnysab 2013-08-22
  • 打赏
  • 举报
回复
引用 8 楼 spirit008 的回复:
把你bind端口和join端口改成一个,另外,ws2的这个joinleaf有毛病,不能用这个socket发单播,组播的话还是用老的方式好一些。 ip_mreq mcast; mcast.imr_interface.S_un.S_addr = INADDR_ANY; mcast.imr_multiaddr.S_un.S_addr = inet_addr("230.0.1.2"); setsockopt(s,IPPROTO_IP,IP_ADD_MEMBERSHIP,(char*)&mcast,sizeof(mcast));
我刚才又看了一下代码,现在总算知道我是哪里错了。 就如您所说,把bind的端口和组播端口改成样的就可以了。 那么如果要发送数据就不用保持一致吧?
sunnysab 2013-08-22
  • 打赏
  • 举报
回复
引用 8 楼 spirit008 的回复:
把你bind端口和join端口改成一个,另外,ws2的这个joinleaf有毛病,不能用这个socket发单播,组播的话还是用老的方式好一些。 ip_mreq mcast; mcast.imr_interface.S_un.S_addr = INADDR_ANY; mcast.imr_multiaddr.S_un.S_addr = inet_addr("230.0.1.2"); setsockopt(s,IPPROTO_IP,IP_ADD_MEMBERSHIP,(char*)&mcast,sizeof(mcast));
学习了!
木头菇 2013-08-22
  • 打赏
  • 举报
回复
给你个代码吧,随手敲了一个
#include "stdafx.h"

#include <WinSock2.h>
#include <WS2tcpip.h>
#include <Windows.h>
#include <stdlib.h>

#define BUFF_SIZE (1024*10)

int _tmain(int argc, _TCHAR* argv[])
{
    WSADATA wsad;
    WSAStartup(MAKEWORD(1,1),&wsad);
    SOCKET s = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
    sockaddr_in local;
    local.sin_family = AF_INET;
    local.sin_addr.S_un.S_addr = INADDR_ANY;
    local.sin_port = htons(10903);
    memset(local.sin_zero,0,8);
    bind(s,(sockaddr*)&local,sizeof(local));
    ip_mreq mcast;
    mcast.imr_interface.S_un.S_addr = INADDR_ANY;
    mcast.imr_multiaddr.S_un.S_addr = inet_addr("230.0.1.2");
    setsockopt(s,IPPROTO_IP,IP_ADD_MEMBERSHIP,(char*)&mcast,sizeof(mcast));

    int loop = 0;
    setsockopt(s,IPPROTO_IP,IP_MULTICAST_LOOP,(char*)&loop,sizeof(int));

    char* recv_buf = (char*)malloc(BUFF_SIZE);

    FILE* f = fopen("d:\\send.txt","r");
    if (f == NULL)
    {
        printf("open file failed.\r\n");
        return 0;
    }
    char* send_buf = (char*)malloc(BUFF_SIZE);
    memset(send_buf,0,BUFF_SIZE);
    int read_size = fread(send_buf,1,BUFF_SIZE,f);


    sockaddr_in remote;  
    remote.sin_addr.S_un.S_addr = inet_addr("230.0.1.2");  
    remote.sin_family = AF_INET;  
    remote.sin_port = htons(10903);  
    memset(remote.sin_zero,0,8);  

    sendto(s,send_buf,read_size,0,(sockaddr*)&remote,sizeof(remote));
    while(1)
    {
        memset(recv_buf,0,BUFF_SIZE);
        sockaddr_in from;
        int fromlen = sizeof(from);
        int rt = recvfrom(s,recv_buf,BUFF_SIZE,0,(sockaddr*)&from,&fromlen);
        if (rt > 0)
        {
            printf("recv : \r\n");
            printf("%s\r\n\r\n",recv_buf);
            printf("total %d bytes.Received %d bytes.\r\n",rt,strlen(recv_buf));

        }
        else
        {
            closesocket(s);
            s = -1;
            break;
        }
    }

	return 0;
}
sunnysab 2013-08-22
  • 打赏
  • 举报
回复
收回#7,可以了,谢谢大家的帮助! 我把这段代码复制到VC中,有个参数改错了 但是原来那段代码一直行不通。。 回头再比对着看看吧,谢谢大家,结贴
木头菇 2013-08-22
  • 打赏
  • 举报
回复
把你bind端口和join端口改成一个,另外,ws2的这个joinleaf有毛病,不能用这个socket发单播,组播的话还是用老的方式好一些。 ip_mreq mcast; mcast.imr_interface.S_un.S_addr = INADDR_ANY; mcast.imr_multiaddr.S_un.S_addr = inet_addr("230.0.1.2"); setsockopt(s,IPPROTO_IP,IP_ADD_MEMBERSHIP,(char*)&mcast,sizeof(mcast));
sunnysab 2013-08-22
  • 打赏
  • 举报
回复
引用 4 楼 VisualEleven 的回复:
找个组播的例子参考一下吧。希望对你有帮助~ http://blog.sina.com.cn/s/blog_4b4c99bd0100ei3u.html
不瞒您说,我就是参考这个文章写的…… 刚才我把这段代码复制到VC中,把几个参数改了改,还是没有用,不过仍然谢谢您! 不知您觉得有没有可能是抓包软件抓错了?
木头菇 2013-08-22
  • 打赏
  • 举报
回复
引用 3 楼 sunnysab 的回复:
我还想请教一下,aja-ntv4-disc是什么意思? 用Wireshark抓包,发送到224.40.40.40的数据包的目标端口竟然是aja-ntv4-disc 用科来网络分析系统2010技术交流版抓包,目标端口是4804
wireshark会根据端口号来猜你是什么协议,例如如果是80,它会猜你是http一样
木头菇 2013-08-22
  • 打赏
  • 举报
回复
怎么搞了两个不一样的端口
Eleven 2013-08-22
  • 打赏
  • 举报
回复
找个组播的例子参考一下吧。希望对你有帮助~ http://blog.sina.com.cn/s/blog_4b4c99bd0100ei3u.html
sunnysab 2013-08-22
  • 打赏
  • 举报
回复
我还想请教一下,aja-ntv4-disc是什么意思? 用Wireshark抓包,发送到224.40.40.40的数据包的目标端口竟然是aja-ntv4-disc 用科来网络分析系统2010技术交流版抓包,目标端口是4804
sunnysab 2013-08-22
  • 打赏
  • 举报
回复
引用 1 楼 VisualEleven 的回复:
value = recvfrom( socket, recvbuffer, 100, 0, (struct sockaddr*)&to, &len); SOCKET写错了,应该是Socket吧 value = recvfrom( Socket, recvbuffer, 100, 0, (struct sockaddr*)&to, &len);
刚才试了一下,同样无效果。
Eleven 2013-08-22
  • 打赏
  • 举报
回复
value = recvfrom( socket, recvbuffer, 100, 0, (struct sockaddr*)&to, &len);
SOCKET写错了,应该是Socket吧
value = recvfrom( Socket, recvbuffer, 100, 0, (struct sockaddr*)&to, &len);

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧