【发布时间】:2020-08-02 23:21:03
【问题描述】:
我用 C 语言编写了一个简单的 TCP 服务器-客户端本机应用程序。它按预期工作(Linux Fedora 以及适用于 Windows 10 的 Cygwin)。当我使用 EM++(或 EMCC)编译它时,它可以很好地构建 JS 和 WASM。
$ em++ TcpService.cpp -o TcpService.js -s ASYNCIFY=1
但是,在运行服务器时,我看到以下错误;虽然它一直在等待客户端数据的到来,但它从未真正连接:
$节点TcpService.js
等待消息到达...
TypeError:无法读取未定义的属性“流”
TypeError:无法读取未定义的属性“流”
...
我将问题缩小到了 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);
}
谷歌搜索错误“TypeError: Cannot read property 'stream' of undefined”并没有证明非常有用,尤其是 WRT 流属性 - 大多数页面只与 AWS 相关,而我的是一个简单的本地测试程序。
在让节点运行应用程序之前,我还安装了所需的 websockets NPM。
【问题讨论】:
-
这是一个非常令人兴奋的项目!你成功了吗?
标签: javascript c++ sockets tcp webassembly