nodejs и winsock, пиши после конца - PullRequest
0 голосов
/ 28 марта 2020

Я пытаюсь настроить TCP-сервер и клиента с nodejs 'net' в качестве сервера и winsock c ++ в качестве клиента. Если я закрою и снова открою соединение с конца c ++, я смогу заставить его работать, однако каждый раз, когда я делаю это, сервер nodejs увеличивает количество клиентов, подключенных к серверу, на 1 каждый раз.

Если я делаю это так, как изложено ниже, первое сообщение отправляется, затем принимается, но во второй раз я получаю эту ошибку: «Ошибка [ERR_STREAM_WRITE_AFTER_END]: запись после завершения»

Error [ERR_STREAM_WRITE_AFTER_END]: write after end
    at writeAfterEnd (_stream_writable.js:264:14)
    at Socket.Writable.write (_stream_writable.js:313:5)
    at Socket.<anonymous> (D:\assignments\nodejs\server.js:38:16)
    at Socket.emit (events.js:311:20)
    at addChunk (_stream_readable.js:294:12)
    at readableAddChunk (_stream_readable.js:271:13)
    at Socket.Readable.push (_stream_readable.js:209:10)
    at TCP.onStreamRead (internal/stream_base_commons.js:186:23)

Если я не использую (клиент / сокет) .end () для события получения данных, приложение c ++ ничего не получает обратно.

Мой вопрос заключается в том, как отправлять и получать сообщения между nodesjs и winsock без необходимости восстановления sh нового соединения после каждого набора данных.

Любая помощь будет высоко ценится, пожалуйста, и спасибо!

Сервер - nodejs

var server = net.createServer(function (client)
{

    console.log('Client connect. Client local address : ' + client.localAddress + ':' + client.localPort + '. client remote address : ' + client.remoteAddress + ':' + client.remotePort);

    client.setEncoding('utf-8');

    client.setTimeout(10000);


    client.on('data', (data) => {
        var msg = decrypt(data, key);
        console.log(msg);
        client.write(encrypt("Hello world", key));   
        client.end();
    });

    // When client send data complete.
    client.on('end', function () {
        console.log('Client disconnect.');

         // Get current connections count.
        server.getConnections(function (err, count) {
            if (!err) {
                // Print current connection count in server console.
                console.log("There are %d connections now. ", count);
            } else {
                console.error(JSON.stringify(err));
            }

        });
    });

    // When client timeout.
    client.on('timeout', function () {
        console.log('Client request time out. ');
    })

    client.on("error", (err) => {
        console.log("Client error: ");
        console.log(err.stack);
    });

});

Клиент - c ++

Настройка winsock

    // Initialize Winsock
    int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != 0) {
        error = "WSAStartup failed with error:" + iResult;
        return false;
    }


#if 1
    struct addrinfo* result = NULL,
        * ptr = NULL,
        hints;

    socketing = true;
    ZeroMemory(&hints, sizeof(hints));
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    // Resolve the server address and port
    iResult = getaddrinfo(DEFAULT_HOST, DEFAULT_PORT, &hints, &result);
    if (iResult != 0) {
        error = "getaddrinfo failed with error:" + iResult;
        return false;
    }


    ConnectSocket = INVALID_SOCKET;

    // Attempt to connect to an address until one succeeds
    for (ptr = result; ptr != NULL; ptr = ptr->ai_next) {

        // Create a SOCKET for connecting to server
        ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype,
            ptr->ai_protocol);
        if (ConnectSocket == INVALID_SOCKET) {
            error = WSAGetLastError();
            continue;
        }

        // Connect to server.
        iResult = connect(ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
        if (iResult == SOCKET_ERROR) {
            closesocket(ConnectSocket);
            ConnectSocket = INVALID_SOCKET;
            continue;
        }
    }

    freeaddrinfo(result);

    if (ConnectSocket == INVALID_SOCKET)
    {
        error = "Unable to connect to server";
        return false;
    }

Код чтения-записи Win sock

 int iResult = send((SOCKET)ConnectSocket, en.c_str(), (int)strlen(en.c_str()), 0);
    if (iResult == SOCKET_ERROR) {
        error = WSAGetLastError();
        closesocket((SOCKET)ConnectSocket);
        WSACleanup();
        return "";
    }

// shutdown the connection since no more data will be sent
//iResult = shutdown(ConnectSocket, SD_SEND);
//if (iResult == SOCKET_ERROR) {
//    closesocket((SOCKET)ConnectSocket);
//    WSACleanup();
//    return "";
//}

fd_set m_readFds;
timeval m_timeInterval;
m_timeInterval.tv_usec = 30;

FD_ZERO(&m_readFds);
FD_SET((SOCKET)ConnectSocket, &m_readFds);
int m_receivedBytes = -1;
sockaddr_in SenderAddr;
int SenderAddrSize = sizeof(SenderAddr);

bool m_acquiringThreadStatus = true;

while (m_acquiringThreadStatus)
{
    FD_CLR((SOCKET)ConnectSocket, &m_readFds);
    FD_SET((SOCKET)ConnectSocket, &m_readFds);

    int m_receivingStatus = select(ConnectSocket, &m_readFds, NULL, NULL, &m_timeInterval);

    if (m_receivingStatus == SOCKET_ERROR)
    {
        return "";
    }

    if (m_receivingStatus == 0)
    {
        continue;
    }


    char recvbuf[DEFAULT_BUFLEN];
    int recvbuflen = DEFAULT_BUFLEN;

    std::string msg;
    do
    {
        m_receivedBytes = recvfrom(ConnectSocket, recvbuf, recvbuflen, 0, (struct sockaddr*) & SenderAddr, &SenderAddrSize);

        if (m_receivedBytes < 0)
        {
            message_request = false;
            socketing = false;
            return "";
        }
        if (m_receivedBytes > 0)
            msg += recvbuf;
        else
        {
            m_acquiringThreadStatus = false;
        }
    } while (m_receivedBytes > 0);


    std::cout << decrypt(msg, get_init_key()) << std::endl;
    return decrypt(msg, get_init_key());

}
return "";
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...