TCP-сервер в Webassembly (C ++) завершается с ошибкой accept () - PullRequest
0 голосов
/ 20 апреля 2020

Я написал простое родное приложение TCP сервер-клиент в C. Он работает как положено (Linux Fedora, а также Cygwin для Windows 10). Когда я скомпилировал его, используя EM ++ (или EM CC), он создал JS & WASM.

$ em ++ TcpService. cpp -o TcpService. js -s ASYNCIFY = 1

Однако во время работы сервера я вижу следующую ошибку; хотя он застрял в ожидании прибытия клиентских данных, он никогда не соединяется:

$ node TcpService. js

Ожидание прибытия сообщений ...

TypeError: Невозможно прочитать свойство 'stream' из неопределенного

TypeError: Невозможно прочитать свойство 'stream' из неопределенного

...

Я сузил проблему до вызова accept (3). Обратите внимание, что ранее я видел стековую трассировку (не очень полезную) в дополнение к вышеупомянутой ошибке TypeError. Теперь, когда я компилирую код с "- s ASYNCIFY = 1" , трассировка стека исчезла. Однако клиентская программа все еще не подключается (ни собственная сборка, ни ее WASM).

Серверная программа использует простые сокеты BSD:

void server(void)
{
  // port to start the server on
  int SERVER_PORT = 8877;

  // socket address used for the server
  struct sockaddr_in _ServerAddr;
  memset(&_ServerAddr, 0, sizeof(_ServerAddr));
  _ServerAddr.sin_family = AF_INET;

  // htons: host to network short: transforms a value in host byte
  // ordering format to a short value in network byte ordering format
  _ServerAddr.sin_port = htons(SERVER_PORT);

  // htonl: host to network long: same as htons but to long
  _ServerAddr.sin_addr.s_addr = htonl(INADDR_ANY);

  // create a TCP socket, creation returns -1 on failure
  int listen_sock;
  if ((listen_sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
    throw std::runtime_error("could not create listen socket\n");
  }

  // bind it to listen to the incoming connections on the created server
  // address, will return -1 on error
  if ((bind(listen_sock, (struct sockaddr *)&_ServerAddr,
            sizeof(_ServerAddr))) < 0) {
    throw std::runtime_error("could not bind socket\n");
  }

  int wait_size = 16;  // maximum number of waiting clients, after which
                       // dropping begins
  if (listen(listen_sock, wait_size) < 0) {
    throw std::runtime_error("could not open socket for listening\n");
  }

  // socket address used to store client address
  struct sockaddr_in client_address;
  int client_address_len = 0;

  // run indefinitely
  while (true) {

    // open a new socket to transmit data per connection
    int sock;
    printf("Waiting for arrival of messages ...\n");
    if ((sock =
             accept(listen_sock, (struct sockaddr *)&client_address,
                    (socklen_t *)&client_address_len)) < 0) {
      throw std::runtime_error("could not open a socket to accept data\n");
    }
    int n = 0;
    int len = 0, maxlen = 100;
    char buffer[maxlen];
    char *pbuffer = buffer;

    printf("client connected with ip address: %s\n",
           inet_ntoa(client_address.sin_addr));

    // keep running as long as the client keeps the connection open
    while ((n = recv(sock, pbuffer, maxlen, 0)) > 0) {
      pbuffer += n;
      maxlen -= n;
      len += n;

      printf("received: '%s'\n", buffer);

      // echo received content back
      send(sock, buffer, len, 0);
    }

    close(sock);
  }

  close(listen_sock);
}

Клиент одинаково прост:

void sendMessage(void)
{
  memset(&server_address, 0, sizeof(server_address));
  server_address.sin_family = AF_INET;

  inet_pton(AF_INET, server_name, &server_address.sin_addr);

  server_address.sin_port = htons(server_port);
  if ((_Sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
    printf("could not create socket\n");
  }

  if (connect(_Sock, (struct sockaddr*)&server_address,
             sizeof(server_address)) < 0) {
    printf("could not connect to server\n");
    return;
  }
  const char* data_to_send = "test message";
  send(_Sock, data_to_send, strlen(data_to_send), 0);
}

Поиск в Google для ошибки «Ошибка типа: невозможно прочитать свойство« поток »из неопределенного» НЕ оказался очень полезным, особенно WRT свойство потока - большинство страниц относятся только к AWS, тогда как моя простая » , локальная тестовая программа.

Я также установил необходимые NPM веб-сокетов, прежде чем смог получить узел для запуска приложения.

...