I'm playing with libuv and I'm trying to have a simple server that listens on localhost and whenever a client connects, just send a "Hello".
The problem is, the server seems to work, but after the first connection the write callback keeps getting called in a loop, never to let go.
Here is a complete code example. What is going wrong?
#include <iostream>
#include <uv.h>
class Server
{
public:
Server() : m_connectionCount(0)
{
struct sockaddr_in addr;
int status = uv_tcp_init(uv_default_loop(), &m_socket);
if(status)
{
exit(1);
}
uv_ip4_addr("0.0.0.0", 8888, &addr);
status = uv_tcp_bind(&m_socket, (const struct sockaddr*) &addr, 0);
if (status)
{
exit(1);
}
m_socket.data = this;
status = uv_listen((uv_stream_t*)&m_socket, 128, [](uv_stream_t* server, int status)
{
Server* pServer = (Server*)server->data;
if(pServer->m_connectionCount >= 2)
return;
uv_tcp_t* client = &(pServer->m_connections[pServer->m_connectionCount]);
int error = uv_tcp_init(uv_default_loop(), client);
if(error)
exit(1);
client->data = pServer;
error = uv_accept(server, (uv_stream_t*)client);
if(error)
exit(1);
auto allocate = [](uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf)
{
buf->base = (char*)malloc(suggested_size);
buf->len = suggested_size;
};
auto onRead = [](uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf)
{
};
error = uv_read_start((uv_stream_t*)client, allocate, onRead);
if(error)
return;
pServer->m_connectionCount++;
for(size_t i=0; i<pServer->m_connectionCount; ++i)
{
uv_stream_t* stream = (uv_stream_t*)&(pServer->m_connections[i]);
uv_buf_t buffer = {.len = 6, .base = "Hello"};
uv_write_t req;
uv_write(&req, stream, &buffer, 1,
[](uv_write_t* request, int status)
{
/*** PROBLEM: After the second client connects this keeps getting called in a loop ... ?***/
printf("Write completed\n");
});
}
});
if (status)
{
exit(1);
}
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
}
private:
uv_tcp_t m_socket;
uv_tcp_t m_connections[2];
uint32_t m_connectionCount;
};
int main(int argc, const char * argv[])
{
Server testServer;
}
P.S. nevermind the leaks and such, this is just put together to illustrate the write callback problem.