Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UV_TCP_ReadLine fails if there are multiple lines to be read #3

Open
rodrimc opened this issue Oct 30, 2016 · 2 comments
Open

UV_TCP_ReadLine fails if there are multiple lines to be read #3

rodrimc opened this issue Oct 30, 2016 · 2 comments

Comments

@rodrimc
Copy link
Contributor

rodrimc commented Oct 30, 2016

If the _uv_tcp_t connection has multiple messages to be read or a single message with a \n, the call UV_TCP_ReadLine fails with the following message:

<ceu-libuv path>/include/uv/stream.ceu:101] runtime error: bug found
For the name of the call (ReadLine) I assume this code should return a single line in each call. The following code illustrates the bug:

server:

#include "uv/uv.ceu"
#include "uv/tcp.ceu"

code/await UV_TCP_Server_Handler (var& _uv_tcp_t client) -> int
do
  loop do
    vector[] byte buffer; 
    await UV_TCP_ReadLine(&client, &buffer);
    _printf ("[server] received: %s\n", &&buffer[0]);

    buffer = [] .. "PONG\n";
    await UV_TCP_Write (&client, &buffer);
#if 0 //Changing to 1 causes the client to fail
    await UV_TCP_Write (&client, &buffer);
#endif
  end
end
#include "uv/tcp-server.ceu"

await UV_TCP_Server ("0.0.0.0", 8888, 128);

client:

#include "uv/uv.ceu"
#include "uv/tcp.ceu"

event& (void) connected;
var& _uv_tcp_t tcp_;
watching UV_TCP_Connect("0.0.0.0", 8888) -> (&tcp_, &connected)
do
  await connected;
  vector []byte buffer = [] .. "PING\n";
  await UV_TCP_Write(&tcp_, &buffer);
  await 1s;

  await UV_TCP_ReadLine(&tcp_, &buffer); //If the server sends two consecutive messages, the client fails here
  _printf ("%s\n", &&buffer[0]); 
end

escape 0;
@fsantanna
Copy link
Collaborator

Currently, UV_Stream_ReadLine expects an end of line exactly at the end of the stream.
It is designed for simple protocols in which peers send a line and block.
If the other peer can send arbitrary messages, you have to use UV_Stream_Read and parse the stream yourself.

@rodrimc
Copy link
Contributor Author

rodrimc commented Oct 31, 2016

Here follows my workaround using UV_Stream_Read:

#include "uv/uv.ceu"
#include "uv/tcp.ceu"

event& (void) connected;
var& _uv_tcp_t tcp_;
watching UV_TCP_Connect("0.0.0.0", 8888) -> (&tcp_, &connected)
do
  await connected;
  vector []byte buffer = [] .. "PING\n";
  await UV_TCP_Write(&tcp_, &buffer);
  await 1s;

  event& usize ok;
  watching UV_Stream_Read(&tcp_, &buffer) -> (&ok) do 
    await ok;
    vector []byte msg = [] .. "";
    var usize i;
    loop i in [0 -> $buffer[ do
      if buffer[i] != 10 then // 10 == \n (ASCII)
        msg = msg .. [ buffer[i] ];
      else
         _printf ("%s\n", &&msg[0]); 
         msg = [] .. ""; 
      end
    end
  end
end
escape 0;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants