chrome.socket如何用于广播或多播? [英] How can chrome.socket be used for broadcasting or multicasting?

查看:319
本文介绍了chrome.socket如何用于广播或多播?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个仅用于局域网的Chrome Packaged应用程序,其中一个实例用作服务器(会话主机),其他实例必须发现服务器并加入会话。这可以通过 chrome.socket 实现吗?



我设置了这样的服务器:

  var socket = chrome.socket || chrome.experimental.socket; 
socket.create('udp',{},function(createInfo){
var publish_socket = createInfo.socketId;
socket.bind(publish_socket,'225.0.0.42',42424,function (result){
if(result< 0)console.error(result); //这工作正常
socket.recvFrom(publish_socket,null,function(recvFromInfo){
console。 log(recvFromInfo); //不能让这个HAPPEN
});
});
// Chrome不会让我监听应用程序窗口关闭
var cleanup_timer;
cleanup_timer = setInterval(function(){
if(requests_window.closed){
socket.destroy(publish_socket);
clearInterval(cleanup_timer);
}
},
5000
);
});

套接字已被绑定,我可以在 ss -ua code $:
$ b $ pre $ 状态Recv-Q发送Q本地地址:端口对端地址:端口
UNCONN 0 0 225.0.0.42:42424 *:*

但服务器从未收到任何数据。我曾尝试使用 nc -uv 225.0.0.42 42424 和chrome.socket API发送一些数据,但没有成功:

  socket.create('udp',{},function(socketInfo){
var socketId = socketInfo.socketId;
socket.sendTo(socketId,str2ab (发现),'225.0.0.42',42424,函数(writeInfo){
if(writeInfo.bytesWritten< 0)console.error(writeInfo);
});
});

这导致错误代码 -15 on客户端和服务器端没有任何东西。



我怀疑应该有一个多播标志设置在某处,但我找不到它。



我使用的是Chrome版本23.0.1246.0 dev

解决方案

do绑定到一个本地接口( 0.0.0.0 ,随机端口起作用,正如您发现的那样),然后将数据包定位到正确的组/端口(是 sendTo 会做的)。



要接收组播数据,您需要绑定到正确的端口 0.0.0.0 没问题),然后加入正确的多播组。你可以用 socket.bind 来完成第一个操作,但第二个操作通常是用 setsockopt 和标记 IP_ADD_MEMBERSHIP 。不幸的是,Chrome套接字API不提供对此的访问。



当您进行此调用时,系统会向网络发送一个IGMP,指示路由器转发多播数据包特定组到您的接口,然后绑定到正确的端口就足以接收它们。您通常也可以指示操作系统使用回送接口复制组播数据包(这样您就可以在同一台机器上使用组播)。如果机器直接连接在一起,你可能会发现现有的代码可以工作,但是如果你通过交换机连接(因为它会丢弃你没有订阅的数据包),而不是如果你在相同的机器(因为数据包不通过回送接口进行路由)。



传统的解决方案是自己创建一个IGMP数据包,这将允许多播工作通过交换机,但不在本地机器上。不幸的是,这需要访问发送原始IP数据包(不是TCP或UDP),而且 chrome.socket 不提供。



这意味着如果没有其他程序以您的名义加入多播组,您将无法收到任何内容。


I want to create a Chrome Packaged App used for LAN only, where one instance serves as a server (session host) and other instances must discover the server and join the session. Can this be achieved with chrome.socket?

I have set up the server like this:

var socket = chrome.socket || chrome.experimental.socket;
socket.create('udp', {}, function(createInfo) {
    var publish_socket = createInfo.socketId;
    socket.bind(publish_socket, '225.0.0.42', 42424, function (result) {
        if (result < 0) console.error(result); // this works fine
        socket.recvFrom(publish_socket, null, function(recvFromInfo) {
            console.log(recvFromInfo); // UNABLE TO MAKE THIS HAPPEN
        });
    });
    // Chrome won't let me listen for app window closing
    var cleanup_timer;
    cleanup_timer = setInterval(function(){
            if (requesting_window.closed) {
                socket.destroy(publish_socket);
                clearInterval(cleanup_timer);
            }
        },
        5000
    );
});

The socket is bound, I can see it in ss -ua:

State      Recv-Q Send-Q      Local Address:Port          Peer Address:Port
UNCONN     0      0           225.0.0.42:42424            *:*

But the server never seems to receive any data. I have tried sending some data using nc -uv 225.0.0.42 42424 and the chrome.socket API but with no success:

socket.create('udp', {}, function(socketInfo) {
   var socketId = socketInfo.socketId;
   socket.sendTo(socketId, str2ab("discovering"), '225.0.0.42', 42424, function(writeInfo) {
       if (writeInfo.bytesWritten < 0) console.error(writeInfo);
   });
});  

This results in error code -15 on the client side and nothing on the server side.

I suspect there should be a multicast flag set somewhere but I couldn't find it.

I am using Chrome Version 23.0.1246.0 dev

解决方案

To send multicast packets all you need to do is bind to a local interface (0.0.0.0 with a random port works, as you've discovered), and then address a packet to the correct group/port (which is what sendTo will do).

To receive multicast data you need to both bind to the correct port (on 0.0.0.0 is fine), then join the correct multicast group. You can do the first bit with socket.bind, but the second is normally done with setsockopt and the flag IP_ADD_MEMBERSHIP. Unfortunately the Chrome socket API doesn't provide access to this.

When you make this call the system sends an IGMP onto the network instructing the routers to forward multicast packets for a specific group to your interface, binding to the correct port is then enough to receive them. You can normally also instruct the OS to duplicate multicast packets with the loopback interface (so you can use multicast on the same machine). You'll probably find that your existing code will work if the machines are connected directly together, but not if you connect via a switch (as it will drop the packets as your haven't subscribed), and not if you're on the same machine (as the packets don't route via the loopback interface).

The traditional solution to this is to create an IGMP packet yourself, which would allow multicast to work via a switch, but not on the local machine. Unfortunately this needs access to send raw IP packets (not TCP or UDP) and chrome.socket doesn't provide that.

This means that without another program to join the multicast group on your behalf you won't be able to receive anything.

这篇关于chrome.socket如何用于广播或多播?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆