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
NodeJS streams, including
net.Socket
s, 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 theend()
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 itsuncork()
method after. The docs forcork()
say: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 ofuncork()
to flush the buffer.Note also the documentation for
uncork()
, especially the part about proper usage:Example:
* In principle. But if you are performing multiple
write()
s then it’s probably sufficient tocork()
before the last non-empty one, because flushing the last one will require flushing any preceding writes, too.With the current implementation your
GetData
function will only return once the peer has shutdown the connection, i.e. calledsocket.end()
. This is because you are callingrecv
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 andrecv
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 ofrecv
in C is the same.