Code Monkey home page Code Monkey logo

uv-cpp's Introduction

uv-cpp

Github release Platform License Project Status: Active – The project has reached a stable, usable state and is being actively developed.


Language Translations:


uv-cpp is a simple interface, high-performance network library based on C++11.

Dependencies

Features

  • C++11 functional/bind style callback instead of C-style function pointer.
  • TCP and UDP wrapper.
  • DNSandHttp:DNS query and http support,Http routing based on radix tree.
  • TimerandTimerWheel:Heartbeat timeout judgment with time complexity of O(1).
  • Async:libuv async wrapper,but optimized the problem of calling multiple times but callback will only be called once.
  • PacketandPacketBuffer:Send and receive packet of Tcp data stream. Support custom data packet structure (such as uvnsq)
  • Log interface.

Build Instructions

  • VS2017 (windows)
  • Codeblocks (linux)
  • CMake (linux)

Benchmark

ping-pong VS boost.asio-1.67


environment:Intel Core i5 8265U + debian8 + gcc8.3.0 + libuv1.30.0 + '-O2'

size peer pack 1K bytes 2K bytes 4K bytes 8K bytes
uv-cpp 16138 kbyte 32071 kbyte 59264 kbyte 123813 kbyte
boost.asio 16119 kbyte 31566 kbyte 58322 kbyte 126210 kbyte

asio1


environment:i5-8265U + 4G memory + 4k bytes ping-pong

concurrency 10 100 1000 5000
uv-cpp 654282 kbyte 591869 kbyte 401500 kbyte 412855 kbyte
boost.asio 633818 kbyte 585716 kbyte 371386 kbyte 382402 kbyte

asio2

Apache bench VS nginx-1.14.2


environment:Intel Core i5 8265U + debian8 + gcc8.3.0 + libuv1.30.0 + '-O2'

1000 concurrency && 100000 request.
uv_http nginx_http

Quick start

A simple echo server

#include <iostream>
#include <uv/include/uv11.h>

int main(int argc, char** args)
{
    uv::EventLoop* loop = uv::EventLoop::DefaultLoop();
	
    uv::TcpServer server(loop);
    server.setMessageCallback([](uv::TcpConnectionPtr ptr,const char* data, ssize_t size)
    {
        ptr->write(data, size, nullptr);
    });
    //server.setTimeout(60); //heartbeat timeout.
	
    uv::SocketAddr addr("0.0.0.0", 10005, uv::SocketAddr::Ipv4);
    server.bindAndListen(addr);
    loop->run();
}

A simple http service router which based on radix tree.

int main(int argc, char** args)
{
    uv::EventLoop loop;
    uv::http::HttpServer::SetBufferMode(uv::GlobalConfig::BufferMode::CycleBuffer);

    uv::http::HttpServer server(&loop);
	
    //example:  127.0.0.1:10010/test
    server.Get("/test",std::bind(&func1,std::placeholders::_1,std::placeholders::_2));
    
    //example:  127.0.0.1:10010/some123abc
    server.Get("/some*",std::bind(&func2, std::placeholders::_1, std::placeholders::_2));
    
    //example:  127.0.0.1:10010/value:1234
    server.Get("/value:",std::bind(&func3, std::placeholders::_1, std::placeholders::_2));
    
    //example:  127.0.0.1:10010/sum?param1=100&param2=23
    server.Get("/sum",std::bind(&func4, std::placeholders::_1, std::placeholders::_2));
    
    uv::SocketAddr addr("127.0.0.1", 10010);
    server.bindAndListen(addr);
    loop.run();
}

More examples here.
API's document here.

uv-cpp's People

Contributors

adivinaelnombre avatar dselivanov avatar twoentartian avatar wlgq2 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

uv-cpp's Issues

勘误

[EventLoop.h]
Line36: DefalutLoop() ->DefaultLoop();
Line42: hanlde() -> handle();
[Timer.h]
Line43: colseComplete() -> closeComplete();

uv::Packet::readFromBuffer 的解包问题?

我在用protobuf作为数据作为发送的有效数据时,发包大小和收包大小是一样的,但是protobuf解析时总是解析失败,后来我跟踪uv::Packet::readFromBuffer的解包流程,发现 uv::Packet::readFromBuffer 在返回解包后的数据时,好像把包头的内容和包尾的内容也包括在内了,后来我处理了一下,就可以解析了,这应该是一个bug吧,具体解决方法是增加对data变量的包头清除和尾的清除
// 解析有效数据包的长度 UnpackNum((uint8_t*)data.c_str() + 1, dataSize); uint16_t msgsize = dataSize + PacketMinSize(); //包不完整 if (size < msgsize) { return -1; } // 去掉包头读取的3字节 data.clear(); packetbuf->clearBufferN(sizeof(dataSize)+1); packetbuf->readBufferN(data, dataSize +1); //检查包尾 if ((uint8_t)data.back() == EndByte) { // 去掉包尾的1字节 data.pop_back(); packetbuf->clearBufferN(dataSize +1); break; }

TimerWheel 类的作用

我看文档里的 TimerWheel 类,说是超时剔除机制,现在有个疑问,就是新连接对象被保存在两个地方了,一个是TcpServer类的connnections_成员中(connnections_中的保存要在客户端主动断开才会被删除),一个是TimerWheel类的wheel_成员中(在指定的超时时间后被删除),超时剔除机制是什么意思呢?是在指定的超时时间后,断开与客户端的连接吗,还是有其它的含义呢?

你好,cmake和make之后该怎么运行helloworld例子

在ubuntu下,我cmake和make之后,生成了libuv_cpp.a静态库,然后我用vscode编译一个helloworld例子,要怎么链接这些库?
vscode的tasks配置文件写成了如下:
但是这样做之后,他还是不能成功的编译出可执行文件,并且报错:EventLoop.cpp:(.text+0x2e):对‘uv_default_loop’未定义的引用,这一系列的链接失败的错误码。

{
    "tasks": [
        {
            "type": "cppbuild",
            "label": "C/C++: g++ 生成活动文件",
            "command": "/usr/bin/g++",
            "args": [
                "-fdiagnostics-color=always",
                "-g",
                "${file}",
                "-I","/home/aoa/Downloads/uv-cpp-master",
                "-I","/home/aoa/Downloads/uv-cpp-master/libuv1.30.0/include",
                "-L","/home/aoa/Downloads/uv-cpp-master/build",
                "-l","uv_cpp",
                "-Wl,-rpath=/home/aoa/Downloads/uv-cpp-master/build",
                "-std=c++11",
                "-Wall",
                "-o",
                "${fileDirname}/${fileBasenameNoExtension}",
            ],
            "options": {
                "cwd": "${fileDirname}"
            },
            "problemMatcher": [
                "$gcc"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "detail": "调试器生成的任务。"
        }
    ],
    "version": "2.0.0"
}
/home/aoa/Downloads/uv-cpp-master/build/libuv_cpp.a(EventLoop.cpp.o):在函数‘uv::EventLoop::~EventLoop()’中:
EventLoop.cpp:(.text+0x2e):对‘uv_default_loop’未定义的引用
EventLoop.cpp:(.text+0x3c):对‘uv_loop_close’未定义的��用
/home/aoa/Downloads/uv-cpp-master/build/libuv_cpp.a(EventLoop.cpp.o):在函数‘uv::EventLoop::EventLoop(uv::EventLoop::Mode)’中:
EventLoop.cpp:(.text+0xbd):对‘uv_default_loop’未定义的引用
EventLoop.cpp:(.text+0x112):对‘uv_loop_init’未定义的引用
/home/aoa/Downloads/uv-cpp-master/build/libuv_cpp.a(EventLoop.cpp.o):在函数‘uv::EventLoop::run()’中:
EventLoop.cpp:(.text+0x1fd):对‘uv_run’未定义的引用
/home/aoa/Downloads/uv-cpp-master/build/libuv_cpp.a(EventLoop.cpp.o):��函数‘uv::EventLoop::runNoWait()’中:
EventLoop.cpp:(.text+0x250):对‘uv_run’未定义的引用
/home/aoa/Downloads/uv-cpp-master/build/libuv_cpp.a(EventLoop.cpp.o):在函数‘std::_Function_handler<void (uv::Async*), uv::EventLoop::stop()::{lambda(uv::Async*)#1}>::_M_invoke(std::_Any_data const&, uv::Async*&&)’���:
EventLoop.cpp:(.text+0x85):对‘uv_stop’未定义的引用
/home/aoa/Downloads/uv-cpp-master/build/libuv_cpp.a(EventLoop.cpp.o):在���数‘uv::EventLoop::GetErrorMessage(int)’中:
EventLoop.cpp:(.text+0x476):对‘uv_strerror’��定义的引用

……………………………………………………………………………………

collect2: error: ld returned 1 exit status

编译问题

可以提供下工程文件或者CMake文件吗

VS2015下使用时编译报错,而且错误很奇怪

我用VS2015编译uv_cpp为静态库后,在新工程中包含include头文件目录,编译时出现如下错误:
\vs2015\vc\include\initializer_list(15): error C2894: templates cannot be declared to have 'C' lin
\vs2015\vc\include\initializer_list(59): error C2894: templates cannot be declared to have 'C' lin
\vs2015\vc\include\initializer_list(66): error C2894: templates cannot be declared to have 'C' lin
\vs2015\vc\include\xtr1common(20): error C2894: templates cannot be declared to have 'C' linkage
\vs2015\vc\include\xtr1common(44): error C2894: templates cannot be declared to have 'C' linkage
\vs2015\vc\include\xtr1common(48): error C2894: templates cannot be declared to have 'C' linkage
\vs2015\vc\include\xtr1common(55): error C2894: templates cannot be declared to have 'C' linkage
\vs2015\vc\include\xtr1common(61): error C2894: templates cannot be declared to have 'C' linkage
\vs2015\vc\include\xtr1common(68): error C2894: templates cannot be declared to have 'C' linkage
\vs2015\vc\include\xtr1common(76): error C2894: templates cannot be declared to have 'C' linkage
\vs2015\vc\include\xtr1common(84): error C2894: templates cannot be declared to have 'C' linkage
\vs2015\vc\include\xtr1common(91): error C2894: templates cannot be declared to have 'C' linkage
\vs2015\vc\include\xtr1common(98): error C2894: templates cannot be declared to have 'C' linkage
\vs2015\vc\include\xtr1common(104): error C2894: templates cannot be declared to have 'C' linkage
\vs2015\vc\include\xtr1common(110): error C2894: templates cannot be declared to have 'C' linkage
\vs2015\vc\include\xtr1common(117): error C2894: templates cannot be declared to have 'C' linkage
\vs2015\vc\include\xtr1common(123): error C2894: templates cannot be declared to have 'C' linkage
\vs2015\vc\include\xtr1common(130): error C2894: templates cannot be declared to have 'C' linkage
\vs2015\vc\include\xtr1common(138): error C2894: templates cannot be declared to have 'C' linkage
\vs2015\vc\include\xtr1common(144): error C2894: templates cannot be declared to have 'C' linkage
\vs2015\vc\include\xtr1common(150): error C2894: templates cannot be declared to have 'C' linkage
\vs2015\vc\include\xtr1common(156): error C2894: templates cannot be declared to have 'C' linkage
\vs2015\vc\include\xtr1common(162): error C2894: templates cannot be declared to have 'C' linkage
\vs2015\vc\include\xtr1common(169): error C2894: templates cannot be declared to have 'C' linkage
\vs2015\vc\include\xtr1common(176): error C2894: templates cannot be declared to have 'C' linkage
\vs2015\vc\include\xtr1common(182): error C2894: templates cannot be declared to have 'C' linkage
\vs2015\vc\include\xtr1common(188): error C2894: templates cannot be declared to have 'C' linkage
\vs2015\vc\include\xtr1common(194): error C2894: templates cannot be declared to have 'C' linkage
\vs2015\vc\include\xtr1common(200): error C2894: templates cannot be declared to have 'C' linkage
\vs2015\vc\include\xtr1common(206): error C2894: templates cannot be declared to have 'C' linkage
\vs2015\vc\include\xtr1common(212): error C2894: templates cannot be declared to have 'C' linkage
\vs2015\vc\include\xtr1common(218): error C2894: templates cannot be declared to have 'C' linkage
\vs2015\vc\include\xtr1common(224): error C2894: templates cannot be declared to have 'C' linkage
\vs2015\vc\include\xtr1common(230): error C2894: templates cannot be declared to have 'C' linkage
\vs2015\vc\include\xtr1common(237): error C2894: templates cannot be declared to have 'C' linkage
\vs2015\vc\include\xtr1common(244): error C2894: templates cannot be declared to have 'C' linkage
\vs2015\vc\include\xtr1common(249): error C2894: templates cannot be declared to have 'C' linkage
\vs2015\vc\include\xtr1common(255): error C2894: templates cannot be declared to have 'C' linkage
不包含uv_cpp的include文件夹时编译没有问题,百思不得其解

内存泄露

EventLoop::~EventLoop()
{
if (loop_ != uv_default_loop())
{
uv_loop_close(loop_);
delete loop_;
delete async_;
}
}

如果loop不为全局静态的也要释放 async_吧

TimerWheel 类的是否会将没有超时连接删除

void uv::TcpServer::onAccept(EventLoop * loop, UVTcpPtr client)
{
string key;
SocketAddr::AddrToStr(client.get(), key, ipv_);

uv::LogWriter::Instance()->debug("new connect  " + key);
shared_ptr<TcpConnection> connection(new TcpConnection(loop, key, client));
if (connection)
{
    connection->setMessageCallback(std::bind(&TcpServer::onMessage, this, placeholders::_1, placeholders::_2, placeholders::_3));
    connection->setConnectCloseCallback(std::bind(&TcpServer::closeConnection, this, placeholders::_1));
    addConnnection(key, connection);
    if (timerWheel_.getTimeout() > 0)
    {
        auto wrapper = std::make_shared<ConnectionWrapper>(connection);
        connection->setWrapper(wrapper);
        timerWheel_.insert(wrapper);
    }
    if (onNewConnectCallback_)
        onNewConnectCallback_(connection);
}
else
{
    uv::LogWriter::Instance()->error("create connection fail. :" + key);
}

}

新连接过来后,会将对应连接插入 std::vector<std::set<std::shared_ptr>> wheel_;

回调过程中会周期的增加index_
template
inline void TimerWheel::wheelCallback()
{
if (!timeoutSec_)
return;
if (++index_ == timeoutSec_)
{
index_ = 0;
}
wheel_[index_].clear();
}
}

若有多个用户情况下,必然会有多个连接公用一共index_,clear过程是否会导致删除多个连接的可能性。

服务端同时开启多个端口

服务端同时开启多个端口,客户端同时连接这些端口
server同时开启多个端口(不同端口处理不同的数据信息,如echo,返回当前时间等等)
client同时连接这些端口发送数据
这样并发处理时会不会产生问题,主要是线程安全和崩溃问题?有没有例子可供参考,谢谢了.

centos 7 运行一晚第二天看到崩溃了

Program received signal SIGSEGV, Segmentation fault.
malloc_consolidate (av=av@entry=0x7ffff6f8c760 <main_arena>) at malloc.c:4147
4147 nextsize = chunksize(nextchunk);
(gdb) bt
#0 malloc_consolidate (av=av@entry=0x7ffff6f8c760 <main_arena>) at malloc.c:4147
#1 0x00007ffff6c4620e in _int_free (av=0x7ffff6f8c760 <main_arena>, p=0x7a92e0, have_lock=0) at malloc.c:4053
#2 0x00000000004e23fa in _M_dispose (__a=..., this=) at /opt/rh/devtoolset-8/root/usr/include/c++/8/ext/atomicity.h:82
#3 _M_dispose (__a=..., this=) at /opt/rh/devtoolset-8/root/usr/include/c++/8/bits/basic_string.h:3250
#4 ~basic_string (this=0x7ba410, __in_chrg=) at /opt/rh/devtoolset-8/root/usr/include/c++/8/bits/basic_string.h:3640
#5 uv::TcpConnection::~TcpConnection (this=0x7ba3d0, __in_chrg=) at /mnt/hgfs/workspace/gitee/metel_sdp/client/third_party/uv-cpp1.5.4/uv/TcpConnection.cpp:44
#6 0x00000000004e1b3a in _M_release (this=0x7ba3c0) at /opt/rh/devtoolset-8/root/usr/include/c++/8/ext/atomicity.h:69
#7 _M_release (this=0x7ba3c0) at /opt/rh/devtoolset-8/root/usr/include/c++/8/bits/shared_ptr_base.h:148
#8 ~__shared_count (this=, __in_chrg=) at /opt/rh/devtoolset-8/root/usr/include/c++/8/bits/shared_ptr_base.h:728
#9 ~__shared_ptr (this=, __in_chrg=) at /opt/rh/devtoolset-8/root/usr/include/c++/8/bits/shared_ptr_base.h:1167
#10 operator= (__r=, this=0x7a8920) at /opt/rh/devtoolset-8/root/usr/include/c++/8/bits/shared_ptr_base.h:1263
#11 operator= (__r=, this=0x7a8920) at /opt/rh/devtoolset-8/root/usr/include/c++/8/bits/shared_ptr.h:335
#12 uv::TcpClient::onConnect(bool) () at /mnt/hgfs/workspace/gitee/metel_sdp/client/third_party/uv-cpp1.5.4/uv/TcpClient.cpp:112
#13 0x00000000004e1c0a in operator() (__closure=0x0, req=, status=) at /mnt/hgfs/workspace/gitee/metel_sdp/client/third_party/uv-cpp1.5.4/uv/TcpClient.cpp:101
#14 uv::TcpClient::connect(uv::SocketAddr&)::{lambda(uv_connect_s*, int)#1}::_FUN(uv_connect_s*, int) () at /mnt/hgfs/workspace/gitee/metel_sdp/client/third_party/uv-cpp1.5.4/uv/TcpClient.cpp:102
#15 0x00000000004f6d0a in uv__stream_connect (stream=0x7baf00) at /mnt/hgfs/workspace/gitee/metel_sdp/client/third_party/libuv-1.42.0/src/unix/stream.c:1391
#16 0x00000000004f6a48 in uv__stream_io (loop=0x7a7010, w=0x7baf88, events=4) at /mnt/hgfs/workspace/gitee/metel_sdp/client/third_party/libuv-1.42.0/src/unix/stream.c:1308
#17 0x0000000000500009 in uv__io_poll (loop=0x7a7010, timeout=312) at /mnt/hgfs/workspace/gitee/metel_sdp/client/third_party/libuv-1.42.0/src/unix/epoll.c:374
#18 0x00000000004ec791 in uv_run (loop=0x7a7010, mode=UV_RUN_DEFAULT) at /mnt/hgfs/workspace/gitee/metel_sdp/client/third_party/libuv-1.42.0/src/unix/core.c:389
#19 0x00000000004df8f0 in uv::EventLoop::run (this=0x7a76b0) at /mnt/hgfs/workspace/gitee/metel_sdp/client/third_party/uv-cpp1.5.4/uv/EventLoop.cpp:67
#20 0x0000000000448218 in main (argc=1, argv=0x7fffffffe628) at /mnt/hgfs/workspace/gitee/metel_sdp/client/sdp/app/main.cpp:101
(gdb) info thread
Id Target Id Frame
6 Thread 0x7ffff488f700 (LWP 3189688) "sdp" pthread_cond_wait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:185
5 Thread 0x7ffff5090700 (LWP 3189687) "sdp" pthread_cond_wait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:185
4 Thread 0x7ffff5891700 (LWP 3189686) "sdp" pthread_cond_wait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:185
3 Thread 0x7ffff6092700 (LWP 3189685) "sdp" pthread_cond_wait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:185
2 Thread 0x7ffff6893700 (LWP 3189682) "sdp" pthread_cond_timedwait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S:238

  • 1 Thread 0x7ffff7fe6780 (LWP 3189678) "sdp" malloc_consolidate (av=av@entry=0x7ffff6f8c760 <main_arena>) at malloc.c:4147
    (gdb)
    网络先断开后重连出现了一次上面的这个问题 uv-cpp1.5.4/uv/TcpClient.cpp:112
    1636078950(1)
    uv-cpp1.5.4/uv/TcpConnection.cpp:44
    1636078990(1)

关于内存的释放问题

我在ubuntu20.04 下用 CodeBlocks跑了一下,好像tcpServer的内存一直没有释放掉,请问一下你那里测试有发现这个情况吗?

`O(1)`复杂度的心跳机制检测询问

这段代码是什么语义呢,为什么每定时器触发一次就清空一次连接对象呢

void TimerWheel::wheelCallback()
{
    if(!timeoutSec_)
        return;
    if(++index_ ==timeoutSec_)
    {
        index_=0;
    }
    wheel[index_].clear();
}

TcpAccepter::bind绑定失败

在centos7.5下使用uv-cpp, 启动echo_server, 在绑定当前服务器的公网IP时, bind失败, 返回(-99)错误: socket_bind(): unable to bind address [99]. (保证IP,端口无错误), 另外启的一个服务器使用相同的IP,端口可正常绑定.是否是libuv在绑定地址端口的时候只能填写(127.0.0.0.1或0.0.0.0). echo_server在更改IP为0.0.0.0后, 可以正常运行.

TcpConnection::write函数中似乎有隐藏的内存泄露问题?

int TcpConnection::write(const char* buf, ssize_t size, AfterWriteCallback callback) { int rst; if (connected_) { WriteReq* req = new WriteReq; req->buf = uv_buf_init(const_cast<char*>(buf), static_cast<unsigned int>(size)); req->callback = callback; auto ptr = handle_.get(); rst = ::uv_write((uv_write_t*)req, (uv_stream_t*)ptr, &req->buf, 1, [](uv_write_t *req, int status) { WriteReq *wr = (WriteReq*)req; if (nullptr != wr->callback) { struct WriteInfo info; info.buf = const_cast<char*>(wr->buf.base); info.size = wr->buf.len; info.status = status; wr->callback(info); } delete wr; }); if (0 != rst) { uv::LogWriter::Instance()->error(std::string("write data error:"+std::to_string(rst))); if (nullptr != callback) { struct WriteInfo info = { rst,const_cast<char*>(buf),static_cast<unsigned long>(size) }; callback(info); } } } else { rst = -1; if (nullptr != callback) { struct WriteInfo info = { WriteInfo::Disconnected,const_cast<char*>(buf),static_cast<unsigned long>(size) }; callback(info); } } return rst; }

上面这段代码中,new了一个 WriteReq 对象 req,如果程序不执行到 delete wr; 语句,那不就有内存泄露呀

TcpServer在客户端断开后发送数据崩溃

刚刚发现一个小问题,客户端和服务端频繁相互发送数据时,TcpClient断开后,TcpConnection被销毁,但是在被销毁之前,在非事件循环线程中通过调用TcpConnection::writeInLoop向事件循环投递一块要发送的数据,由于不在事件循环中,所以这个待发送数据被放入了EventLoop类对象的待发送队列中(async_数据成员):
image
但是当这个发送数据的请求被执行时,TcpConnection连接对象已经被销毁,所以在写入数据时会崩溃,问题代码应该在这里:
image
这里将this指针作为lambda表达式的捕获参数,当TcpConnnection对象被释放了之后,this指针指向被释放的内存,所以会造成崩溃,我尝试改成如下方式,用TcpConnection的弱引用来代替this指针,在lambda表达式内部
检测TcpConnection连接对象是否有效:
image

编译出错

我在新建的空项目中,把 uv 中的代码拷贝进来,编译报错,报错信息如下,使用的IDE是vs2019
image

uv-cpp做客户端时,当服务端连不上,重复去连接时,无论是linux还是Windows都会奔溃

image

linux的崩溃
#0 0x0000000000592310 in ?? ()
#1 0x00000000004f52dc in uv__io_poll (loop=0x578c60 <default_loop_struct>, timeout=161) at /mnt/hgfs/workspace/metel_sdp/client/third_party/libuv-1.42.0/src/unix/epoll.c:374
#2 0x00000000004e1a28 in uv_run (loop=0x578c60 <default_loop_struct>, mode=UV_RUN_DEFAULT) at /mnt/hgfs/workspace/metel_sdp/client/third_party/libuv-1.42.0/src/unix/core.c:389
#3 0x00000000004d5b80 in uv::EventLoop::run (this=0x578a20 uv::EventLoop::DefaultLoop()::defaultLoop) at /mnt/hgfs/workspace/metel_sdp/client/third_party/uv-cpp1.5.4/uv/EventLoop.cpp:67
#4 0x00000000004153c6 in main () at /mnt/hgfs/workspace/metel_sdp/client/sdp/app/main.cpp:99
#5 0x00007ffff6be7555 in __libc_start_main (main=0x414f30

, argc=1, argv=0x7fffffffe628, init=, fini=, rtld_fini=, stack_end=0x7fffffffe618) at ../csu/libc-start.c:266
#6 0x000000000041788f in _start () at /opt/rh/devtoolset-9/root/usr/include/c++/9/bits/basic_string.h:3901

client跨线程循环发送时候 ,client崩溃

如题
image
客户端:
int main()
{
//定义事件分发器类
EventLoop* loop = new EventLoop();
#if TEST_IPV6
SocketAddr addr2("0:0:0:0:0:0:0:1", 10002, SocketAddr::Ipv6);
#else
SocketAddr addr2("127.0.0.1", 10002, SocketAddr::Ipv4);
#endif

LiteTcpClient client(loop);
client.connectToServer(addr2);

#if 1

//跨线程发送数据
std::thread thread([&client]()
{
	std::this_thread::sleep_for(std::chrono::milliseconds(2000));
	char* data = new char[4]{ 't','e','s','t' };
	while (1) {
		client.write(data, sizeof(data));

	}
});

#endif

loop->run();

服务端:
class LiteTcpServer :public uv::TcpServer
{
public:
LiteTcpServer(uv::EventLoop* loop)
:TcpServer(loop)
{
setMessageCallback(std::bind(&LiteTcpServer::newMessage, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
}
private:
void newMessage(uv::TcpConnectionPtr connection, const char* buf, ssize_t size)
{
//不使用buffer
if (uv::GlobalConfig::BufferModeStatus == uv::GlobalConfig::NoBuffer)
{
std::cout << "receive data :" << std::string(buf, size) << std::endl;
char msg[255] = "Hello,I am Server";
#if 1 //直接发送
//connection->write(buf, size, nullptr);
connection->write(msg, sizeof(msg), nullptr);
。。。。

TCPServer

请问, uv-pp在TCP服务器下, 怎么开启多线程模式呢?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.