end, SOL_SOCKET, SO_REUSEADDR, (char*)&bReuse, sizeof(BOOL));
41
42 int nTTL = 64;
43 // 设置多播封包的TTL值
44 ::setsockopt(sSend,
45 IPPROTO_IP, IP_MULTICAST_TTL, (char*)&nTTL, sizeof(int));
46
47 DWORD dwLocalAddr;
48 // 设置要使用的发送接口
49 setsockopt(sSend,
50 IPPROTO_IP, IP_MULTICAST_IF, (char*)&dwLocalAddr, sizeof(dwLocalAddr));
51
52
53 char szText[] = "Multicasting Test 1";
54
55 sockaddr_in dest;
56 dest.sin_family = AF_INET;
57 dest.sin_addr.S_un.S_addr = inet_addr("234.5.6.7");
58 dest.sin_port = ::ntohs(4567);
59
60 sendto(sSend,szText,strlen(szText),0, (sockaddr*)&dest, sizeof(dest));
61
62 printf("Send Success No.1");
63 closesocket(sSend);
64
65 Sleep(INFINITE);
66
67 return 0;
68
69 }
先运行A中接收程序,在B中运行发送程序。A收到消息,证明发送成功。查看抓包软件。
从抓包软件可以看出,发到不同组的包,目的IP就是对应的组地址。然后我们来测试向QQ群中发送消息。
由于QQ消息是加密的,我们不能确定哪两个是我们发送出去的包。但是,所有包的目的IP都是183.232.127.242,并不像我们刚才的组播的包那样不同组播使用不同组播地址。这个地址应该就是腾讯服务器的地址。然后我们又测试了发文件,私聊消息等。发现除了发送文件是两台计算机经过路由器直接发送外,其他消息都是发往这个地址。现在已经可以排除群聊用的是组播,最有可能是服务器转发。
最后成功的说服了老师否定了题目。之前老师认为是组播而不是服务器转发是因为他感觉这样服务器压力太大。不过按说凭腾讯的实力做到这点应该不会有什么问题。
在网上也有很多人对这个问题进行讨论。通过筛选我确定了三个最有可能的方法。一是在群里指定几个网速快的用户作为Server将消息转发,比如指定群中有100人,指定五个人作为Server,每个用户发送的消息会发给这五个人,在由他们向其他人转发。这个方法管理起来可能会比较麻烦。而是服务器为每个群维护一个用户列表,群消息发送给服务器,由服务器向每个人转发。这个方法对服务器开销很大。三是P2P和服务器转发相结合。