组播接收TCP数据包的问题

时间:2015-03-18 15:16:47

标签: sockets linux-device-driver embedded-linux

我创建了一个网络设备,可以组播dev-> flags = IFF_MULTICAST。

如果我发送UDP消息。这工作正常,我正确地在另一个插槽中收到消息。我将两个套接字定义为:

sockEnvio = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);  

memset(&server, 0, sizeof(server));    
server.sin6_family = AF_INET6;    
server.sin6_scope_id = if_nametoindex("eth2");    
server.sin6_port = htons(15118);    
bind(sockEnvio, (struct sockaddr *)&server, sizeof(server));  

int optval = 1;    
setsockopt(sockEnvio, IPPROTO_IPV6, IPV6_RECVPKTINFO, &optval, sizeof(optval));

optval = 0;        
setsockopt(sockEnvio, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &optval, sizeof(optval));

struct ipv6_mreq mreq;    
memset(&mreq, 0, sizeof(mreq));    
mreq.ipv6mr_interface = if_nametoindex("eth2");    
mreq.ipv6mr_multiaddr.s6_addr[ 0] = 0xff;    
mreq.ipv6mr_multiaddr.s6_addr[ 1] = 0x02;    
mreq.ipv6mr_multiaddr.s6_addr[15] = 0x02;    
setsockopt(sockEnvio, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq, sizeof(mreq))

但是如果我发送TCP消息抛出客户端,当我在服务器上收到数据包时,我没有收到tcp消息。我将客户定义为:

sockTCP = socket(AF_INET6, SOCK_STREAM,0))

memset(&client, 0, sizeof(client));
client.sin6_family = AF_INET6;
client.sin6_scope_id = if_nametoindex("eth2");
client.sin6_port = htons(50118); 
inet_pton(AF_INET6,"fe80:0000:0000:0000:02b0:52ff:feff:ff02",(void*)&client.sin6_addr.s6_addr);

bind(sockTCP, (struct sockaddr *)&client, sizeof(client));

struct hostent *hp;
hp = gethostbyname2("fe80::a2b0:c0ff:fed0:e0f0",AF_INET6);
if (hp == NULL) {
   printf("ERROR, no such host  \n");
}

memset(&from2, 0, sizeof(from2));
from2.sin6_family = AF_INET6;
from2.sin6_port = htons(50117); 
inet_pton(AF_INET6,"fe80::a2b0:c0ff:fed0:e0f0",(void*)&from2.sin6_addr.s6_addr);

int optval = 1;
setsockopt(sockTCP, IPPROTO_IPV6, IPV6_RECVPKTINFO, &optval, sizeof(optval));
optval = 0;
setsockopt(sockTCP, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &optval, sizeof(optval));

connect(sockTCP, (struct sockaddr *)&from2, sizeof(from2));

我将服务器套接字定义为:

sockEnvioTCP = socket(AF_INET6, SOCK_STREAM,0))

memset(&server, 0, sizeof(server));    
server.sin6_family = AF_INET6;
server.sin6_scope_id = if_nametoindex("eth2");
server.sin6_port = htons(50117);
server.sin6_addr = in6addr_any;

int optval = 1;
setsockopt(sockEnvioTCP, IPPROTO_IPV6, IPV6_RECVPKTINFO, &optval, sizeof(optval));    
optval = 0;
setsockopt(sockEnvioTCP, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &optval, sizeof(optval));

bind(sockTCP, (struct sockaddr *)&server, sizeof(server));

listen(sockTCP, 5);
accept(sockTCP, (struct sockaddr *) &from, sizeof(from));

服务器上的系统跟踪是:

ipv6_rcv()
    |--> ip6_route_input()
          |-->ip6_mc_input()
              |-->icmpv6_rcv()

在客户端中,gethostbyname2(...)不是NULL。

在服务器中,ICMP消息的类型是135(Neighbor Solicitation)。目标地址为“ff2:00:00:00:00:01:ffd0:e0f0”。ipv6_chk_mcast_addr()在函数ip6_mc_input()中返回的值有时是1,其他时间是0。

在UDP套接字上,我必须加入目标组播组。但是如何在TCP套接字中创建呢?

有什么想法吗?

感谢。

1 个答案:

答案 0 :(得分:1)

TCP是一种纯粹的端到端协议,不支持多播。 现在您可能想知道为什么会这样? TCP正在不断地将ack从一个对等体发送到另一个对等体,以确认它已正确接收的字节,因为它是一个流式传输协议。如果这样的确认没有到达,则TCP将重新发送,如果需要则多次。 现在假设它是多播的,那么TCP将需要监视其他几个的收据确认。如果您考虑一下这一点,知道TCP已经相当复杂,您可能会意识到为什么它不受支持。