12

我正在尝试将我用 C 和 C++ 编写的桌面应用程序移植到 webassembly 平台,并正在调查是否有可能。该应用程序所做的重要事情之一是通过发送和接收 UDP 消息进行通信。我已经实现了最小的 UDP 客户端,它只创建 UDP 套接字并将数据包发送到服务器(它是本地构建的,并且在同一台机器上作为单独的可执行文件运行)。socket、bind 和 sendto API 没有返回错误,一切看起来都正常,但是服务器端没有接收到消息,wireshark 显示该端口上没有任何活动。

UDP 套接字只是在 webassembly libc 端口上存根,还是在某些 Web 标准连接(例如 WebRTC)之上实现?

客户端代码如下。我检查了本机构建是否正常工作。

#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>

#define BUFLEN 512
#define NPACK 100
#define PORT 9930

void diep(char *s)
{
  perror(s);
  exit(1);
}

#define SRV_IP "127.0.0.1"


int main(void)
{
  struct sockaddr_in si_other;
  int s, i, slen=sizeof(si_other);
  char buf[BUFLEN];

  if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1)
    diep("socket");

  memset((char *) &si_other, 0, sizeof(si_other));
  si_other.sin_family = AF_INET;
  si_other.sin_port = htons(PORT);
  if (inet_aton(SRV_IP, &si_other.sin_addr)==0) {
    fprintf(stderr, "inet_aton() failed\n");
    exit(1);
  }

  for (i=0; i<NPACK; i++) {
    printf("Sending packet %d\n", i);
    sprintf(buf, "This is packet %d\n", i);
    if (sendto(s, buf, BUFLEN, 0, (struct sockaddr*)&si_other, slen)==-1)
      diep("sendto()");
  }

  close(s);
  return 0;
}

我按照http://webassembly.org/getting-started/developers-guide/的说明构建和运行它。

提前感谢您的任何帮助或线索!

4

2 回答 2

6

I found how UDP sockets are implemented at webassembly. Actually, they are emulated by websockets. It probably would work if both client and server were webassemblies, but my server is built natively. As wasm doesn't support dynamic linking, all the code (including libc implementation) is bundled to one JS file, were we can find UDP sendto implementation:

// if we're emulating a connection-less dgram socket and don't have
      // a cached connection, queue the buffer to send upon connect and
      // lie, saying the data was sent now.
      if (sock.type === 2) {
        if (!dest || dest.socket.readyState !== dest.socket.OPEN) {
          // if we're not connected, open a new connection
          if (!dest || dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) {
            dest = SOCKFS.websocket_sock_ops.createPeer(sock, addr, port);
          }
          dest.dgram_send_queue.push(data);
          return length;
        }
      }
于 2017-06-30T12:06:08.153 回答
4

在浏览器中运行的任何东西都不会为您提供本机套接字访问,我怀疑浏览器供应商会强烈反对任何此类访问,因为它是潜在的安全违规行为。

也许随着越来越多的本地应用程序迁移到网络上,由于 webassembly 和类似的举措导致性能差异缩小,并且类似的举措会让他们改变立场,但在那之前,任何想要直接套接字控制的东西都必须保持本地应用程序。

于 2017-07-01T07:51:17.147 回答