UDP socket at webassembly
Asked Answered
S

3

12

I'm trying to port my desktop app written in C and C++ to webassembly platform and am investigating if it is possible at all. One of important things the app does is communicate by sending and receiving UDP messages. I have implemented minimal UDP client which just creates UDP socket and sends packets to server (which is build natively and is running as separate executable at the same machine). socket, bind and sendto APIs return no error and everything looks working but no messages are receiving on server side and wireshark shows no activity on that port.

Is UDP socket just stubbed at webassembly libc port, or it is implemented on top of some web standard connection (e.g. WebRTC)?

The client code is below. I checked that native build is working properly.

#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;
}

I followed instructions from http://webassembly.org/getting-started/developers-guide/ to build and run it.

Thanks in advance for any help or clues!

Salesin answered 29/6, 2017 at 7:52 Comment(5)
Wether Wireshark is able to capture packets on the loopback interface (i.e. sending packets to the very same machine) depends on the platform and your selection of the packet sniffer interface. On Windows + winpcap, for example, it's just not possible. What platform are you on?Kentish
Yes, I'm on Windows, and I will try putting server to anoher machine. Thank you!Salesin
I have tried to send packets to the remote host. Now wireshark shows outgoing packets if I run natively built client app and shows nothing for webassembly build.Salesin
WebAssembly simply only supports TCP sockets, because the generated traffic is embedded into Websockets. What you want doesn't work in WebAssembly.Kentish
tofro, that's right, thank you. I already found how it' made at wasm.Salesin
S
7

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;
        }
      }
Salesin answered 30/6, 2017 at 12:6 Comment(0)
A
4

Anything that runs in the browser will not give you native socket access and I suspect that browser vendors would strongly object to any such access as it is a potential security violation.

Perhaps as more and more native applications move to the web as the performance difference shrinks due to webassembly and similar initiatives would make them change their stance, but until then, anything that wants direct socket control would have to remain a native app.

Applicative answered 1/7, 2017 at 7:51 Comment(3)
Well, I hoped that there's some clever UDP socket implementation on top of WebRTC or even on top of experimantal support of that W3C draft.Salesin
You'd think they'd give some access to UDP since it's useful for some things like realtime audio :\Dangle
@AdnanY : native clients apps can be launched in a similar manner to JavaScript applications and they provided raw sockets.Likable
B
0

Using sockets in code running in a browser should be(come) possible with the direct-sockets API. See https://wicg.github.io/direct-sockets/ for the complete specification.

Also see https://github.com/WICG/direct-sockets/

A working TCP socket example is here: https://github.com/googlechromelabs/telnet-client

Bride answered 9/5 at 1:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.