skip to Main Content

This question ask exactly the same but have no answers

When on server side:

socket.write(Buffer.from("123"));

Then on client side:

recv(socket_fd, buffer, 3, 0);

connection stucks..

However

socket.end(Buffer.from("123"));

doesn’t stuck the connection. And I understand why ( at least I think that I do ).
But it closes the socket for reading on client side ( You still can send data )
So You need once again create new socket to read data.

Question:
Is there a way to

 socket.write(Buffer.from("something"))

and receive it on client side without

socket.end();

UPD:
client side recv():

char *GetData(int socket_fd)
{
    char init[] = {0x17, 0x22};
    int bytes_read, n_reads = 0;
    char *buffer = (char *)malloc(BUFFER_SIZE);
    if (buffer == NULL)
    {
        puts("failedn");
        exit(EXIT_FAILURE);
    }
    send(socket_fd, init, 2, 0);
    int offset = 0;
    while ((bytes_read = recv(socket_fd, buffer + offset, BUFFER_SIZE, 0)) > 0)
    {
        if (bytes_read == -1)
        {
            puts("recv failedn");
            exit(EXIT_FAILURE);
        }
        offset += bytes_read;
        char *tmp = realloc(buffer, offset + BUFFER_SIZE);
        if (tmp == NULL)
        {
            puts("realloc failedn");
            exit(EXIT_FAILURE);
        }
        buffer = tmp;
    }
    return buffer;
}

2

Answers


  1. NodeJS streams, including net.Sockets, are buffered. By default, writable streams will accumulate the data you write to them in local memory until they are good and ready to send it to the output device, or until you signal (via the end() method) that no more data will be forthcoming.

    Details of when different streams decide to send data may depend in part on the kind of stream. All are likely to do so once the amount of buffered data reaches a threshold value. Some may additionally do so if a certain amount of time has elapsed since the last write, or under various other circumstances. Generally speaking, however, NodeJS writable streams such as net.Socket may buffer small amounts of output for a long time.

    One way to control that would be by invoking the socket’s cork() method before you write,* and then invoking its uncork() method after. The docs for cork() say:

    The writable.cork() method forces all written data to be buffered in memory. The buffered data will be flushed when either the stream.uncork() or stream.end() methods are called.

    The point to understand in this case is that NodeJS streams buffer data anyway, so using cork() here is not so much to request that, nor necessarily to combine multiple small writes, but principally to enable use of uncork() to flush the buffer.

    Note also the documentation for uncork(), especially the part about proper usage:

    The writable.uncork() method flushes all data buffered since stream.cork() was called.

    When using writable.cork() and writable.uncork() to manage the buffering of writes to a stream, defer calls to writable.uncork() using process.nextTick(). Doing so allows batching of all writable.write() calls that occur within a given Node.js event loop phase.

    Example:

    socket.cork();
    socket.write(Buffer.from("something"));
    // ...
    process.nextTick(() => socket.uncork());
    

    * In principle. But if you are performing multiple write()s then it’s probably sufficient to cork() before the last non-empty one, because flushing the last one will require flushing any preceding writes, too.

    Login or Signup to reply.
  2. With the current implementation your GetData function will only return once the peer has shutdown the connection, i.e. called socket.end(). This is because you are calling recv again and again – until it returns 0 which signals shutdown by the peer or until it returns an error.

    This is likely due to a wrong assumption that recv will return with <=0 if the "message" send by the peer is complete. Only, TCP has no concept of a message. It is only a byte stream and recv will block until it has read more bytes or until the peer has shutdown.

    For more on this see How does socket recv function detects end of message, How does the python socket.recv() method know that the end of the message has been reached?, How to determine if I received entire message from recv() calls. Note that it does not matter that some of these question ask about Python recv function, since the behavior of recv in C is the same.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search