cylix / tacopie Goto Github PK
View Code? Open in Web Editor NEWC++ TCP Library - NO LONGER MAINTAINED
License: MIT License
C++ TCP Library - NO LONGER MAINTAINED
License: MIT License
select is used as the I/O multiplexing tool, can it be changed with poll or epoll
[ 11%] Building CXX object CMakeFiles/tacopie.dir/sources/utils/thread_pool.cpp.o In file included from /home/karl/appserver/cpp_redis/tacopie/sources/utils/thread_pool.cpp:24:0: /home/karl/appserver/cpp_redis/tacopie/includes/tacopie/utils/thread_pool.hpp:48:16: error: ‘function’ in namespace ‘std’ does not name a template type typedef std::function<void()> task_t;
Please add include to <fuctional>
.
Hi! After successfully first connection and disconnection I cant make another connection to server. What can be wrong?
On versions 2.4.2 and before async_read would always call the callback with read_result.sucess == false after the read is finished.
After 2.4.2, this no longer appears to always be the case, in fact, after the client has finished sending all its info and disconnected, some of the time the callback won't be triggered at all.
Tested on Visual Studio 2017.
Hi, I am using the tacopie server to handle a server internal to my application (a recovery server) and want to send a lot of messages. But the problem i see is immediately after all the async_writes the connection gets terminated even without checking if all the messages were successfully written onto the socket. Is there any way to confirm the same or at least wait till all the messages are flushed onto the socket.
Thanks,
Siril.
The documentation for tacopie::tcp_client::write_request
implies that tacopie::tcp_client::async_read()
calls the callback after reading a user-defined number of bytes from the network stream, but this is not the case. It will read AT MOST write_request.size
bytes. The callback will be invoked even if a lesser number of bytes have been read. I'm not sure if this is how it's supposed to work or not, but it makes reading length-prefixed messages a little more complicated (ie. I don't really want to have to resort to using an awkward callback loop, or just directly using the tcp_client's socket)
I've read your code carefully recent days,learning your program skills. But I'm confused about the role of self_pipe in class io_service. How does it work?
Does this library support Unicode? I want to deal with Unicode characters.
This is really a very good library if you remove the usage of c++ exception!!!!!!VERY BAD DESIGN
See...My app crashed just because I didn't use 'try...catch...'
If you follow Microsoft, you will dead in the end!
TCP network transport sticky problem。
I'm using tacopie as part of the cpp_redis library. I'm seeing extremely high CPU usage (nearly 100%) on a system that is not making any calls to the redis server.
The root cause seems to be in the use of self_pipe in the io_service. The two uses of self_pipe that I don't understand are on io_service.cpp:160. In this instance you always notify the pipe that it should wake up, but it seems like the pipe should only be woken up if the state of the socket changed (in other words m_notifier.notify(), should be moved inside to io_service.cpp:158 (inside the if block). I don't see similar usage inside process_wr_event, and I'm wondering why that's the case.
The other usage of self_pipe that I don't understand is in the process_events() function (io_service.cpp:130). Could you help me understand why the pipe needs to be written to at the end of this function?
I uploaded a patch I think might help resolve the high CPU usage.
Thanks!
-DH
Hello,
First, I'd like to say I find "tacopie" a very well written and documented library. It is hard to find something this good and self-contained these days.
My plan is to bind tcp_server to any port available in the system. I did not find any documented way of doing this with tacopie, while Winsock Reference for bind()
function says: "For TCP/IP, if the port is specified as zero, the service provider assigns a unique port to the application from the dynamic client port range."
I have tried passing 0 as a port value to tcp_server.start()
function:
tacopie::tcp_server server;
server.start("127.0.0.1", 0, callback);
However, this will fail inside tcp_socket::create_socket_if_necessary()
function throwing exception due to following ternary operator:
m_fd = socket(m_port == 0 ? AF_UNIX : AF_INET, SOCK_STREAM, 0);
Is there a documented way to achieve this with tacopie that I am not aware of?
Thank you.
Hi,
I'm using cpp_redis in a multithreaded environment. Running DRD on several usecases, it seems that this function is not thread safe as confirmed by linux man page.
Cheers,
Hi, I'am trying to build a dll library on Windows, but got linking error:
Severity Code Description Project File Line Suppression State
Error LNK2001 unresolved external symbol __imp_listen tacopie Z:\cpp_redis4.2.0\cpp_redis-4.2.0\tacopie\msvc15\tcp_socket.obj 1
Error LNK1120 20 unresolved externals tacopie Z:\cpp_redis4.2.0\cpp_redis-4.2.0\msvc15\x64\Release\tacopie.dll 1
Error LNK2001 unresolved external symbol __imp_accept tacopie Z:\cpp_redis4.2.0\cpp_redis-4.2.0\tacopie\msvc15\tcp_socket.obj 1
Error LNK2001 unresolved external symbol __imp_bind tacopie Z:\cpp_redis4.2.0\cpp_redis-4.2.0\tacopie\msvc15\windows_self_pipe.obj 1
Error LNK2001 unresolved external symbol __imp_closesocket tacopie Z:\cpp_redis4.2.0\cpp_redis-4.2.0\tacopie\msvc15\windows_self_pipe.obj 1
Error LNK2001 unresolved external symbol __imp_connect tacopie Z:\cpp_redis4.2.0\cpp_redis-4.2.0\tacopie\msvc15\windows_self_pipe.obj 1
Error LNK2001 unresolved external symbol __imp_freeaddrinfo tacopie Z:\cpp_redis4.2.0\cpp_redis-4.2.0\tacopie\msvc15\windows_tcp_socket.obj 1
Error LNK2001 unresolved external symbol __imp_getaddrinfo tacopie Z:\cpp_redis4.2.0\cpp_redis-4.2.0\tacopie\msvc15\windows_tcp_socket.obj 1
Error LNK2001 unresolved external symbol __imp_getsockname tacopie Z:\cpp_redis4.2.0\cpp_redis-4.2.0\tacopie\msvc15\windows_self_pipe.obj 1
Error LNK2001 unresolved external symbol __imp_htonl tacopie Z:\cpp_redis4.2.0\cpp_redis-4.2.0\tacopie\msvc15\windows_self_pipe.obj 1
Error LNK2001 unresolved external symbol __imp_htons tacopie Z:\cpp_redis4.2.0\cpp_redis-4.2.0\tacopie\msvc15\windows_tcp_socket.obj 1
Error LNK2001 unresolved external symbol __imp_inet_ntoa tacopie Z:\cpp_redis4.2.0\cpp_redis-4.2.0\tacopie\msvc15\tcp_socket.obj 1
Error LNK2001 unresolved external symbol __imp_ioctlsocket tacopie Z:\cpp_redis4.2.0\cpp_redis-4.2.0\tacopie\msvc15\windows_self_pipe.obj 1
Error LNK2001 unresolved external symbol __imp_recv tacopie Z:\cpp_redis4.2.0\cpp_redis-4.2.0\tacopie\msvc15\tcp_socket.obj 1
Error LNK2001 unresolved external symbol __imp_recvfrom tacopie Z:\cpp_redis4.2.0\cpp_redis-4.2.0\tacopie\msvc15\windows_self_pipe.obj 1
Error LNK2001 unresolved external symbol __imp_select tacopie Z:\cpp_redis4.2.0\cpp_redis-4.2.0\tacopie\msvc15\io_service.obj 1
Error LNK2001 unresolved external symbol __imp_send tacopie Z:\cpp_redis4.2.0\cpp_redis-4.2.0\tacopie\msvc15\tcp_socket.obj 1
Error LNK2001 unresolved external symbol __imp_sendto tacopie Z:\cpp_redis4.2.0\cpp_redis-4.2.0\tacopie\msvc15\windows_self_pipe.obj 1
Error LNK2001 unresolved external symbol __imp_socket tacopie Z:\cpp_redis4.2.0\cpp_redis-4.2.0\tacopie\msvc15\windows_self_pipe.obj 1
Error LNK2001 unresolved external symbol __imp_WSAGetLastError tacopie Z:\cpp_redis4.2.0\cpp_redis-4.2.0\tacopie\msvc15\windows_tcp_socket.obj 1
Error LNK2001 unresolved external symbol __WSAFDIsSet tacopie Z:\cpp_redis4.2.0\cpp_redis-4.2.0\tacopie\msvc15\io_service.obj 1
How to reproduce:
Hi, I encountered problem on both my machines when trying to build cpp_redis using methods described for windows build from that repo's wiki. It turned out that the issue was regarded to Winsock2, which is related to this project.
I was getting errors like "undefined external symbol _impl_socket ..." form object files built by tacopie (120+ of them), upon trying to link my project to already built .libs .
It appears that VS15 (VS 2017) and CMake dont get along well, and generated projects miss linkage with ws2_32, that is present in CMakeLists.
Adding it manually via
(tacopie)Project->Properties->Librarian->Additional Dependencies->
(input)ws2_32.lib
seemed to solve the problem.
Cheers!
Some specifics:
Visual Studio 2017 15.3.0, Visual Studio Tools for CMake 1.0
Project files generated separately by CMake v 3.8.0
I am trying to serve up some html content to a browser over a tacopie server. This was my message handler - where I tried both sync and async writes and trying to close the connection when done. Neither works, maybe because I dont understand how the write/disconnect works. Any ideas? thank you!
void on_new_message(const std::shared_ptr<tacopie::tcp_client>& client, const tacopie::tcp_client::read_result& res) {
if (res.success) {
std::string resp = "this is the response";
std::string fullResp = "HTTP/ 1.1 200 OK\r\nContent-Type: type/html\r\nConnection: Closed\r\n Content-Length: "
+ std::to_string(resp.length()) + std::string("\r\n\r\n") + resp;
std::vector<char> buf(fullResp.begin(), fullResp.end());
client->get_socket().send(buf, fullResp.length());
//client->async_write({ buf, nullptr });
client->disconnect();
}
else {
info("WebClient disconnected");
client->disconnect();
}
}
I've tested the client code and I get this error if I use a wrong port number:
terminate called after throwing an instance of 'tacopie::tacopie_error'
what(): connect() failure
Some operating systems (such as IOS), socket defaults to non blocking. When the connect set to timeout is 0, the connection will fail.
sorry for my poor english.^_^
Hello,
First of all , thanks for this nice lib.
I was trying to compile on win 10 , vis. std. 2017, and getting unresolved external errors.
After some digging I realize that
#pragma comment(lib, "ws2_32.lib")
line should be added (i added it in #ifdef _win32 definition )
This needed for both client and server examples.
Best regards,
严重性 代码 说明 项目 文件 行 禁止显示状态
警告 MSB8027 Two or more files with the name of tcp_socket.cpp will produce outputs to the same location. This can lead to an incorrect build result. The files involved are ..\Classes\socket\tacopie\network\common\tcp_socket.cpp, ..\Classes\socket\tacopie\network\unix\tcp_socket.cpp, ..\Classes\socket\tacopie\network\windows\tcp_socket.cpp. test C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V140\Microsoft.CppBuild.targets 936
Hello, nice library. I'd like to use it but straight away I have encountered this problem.
Built OK under MSYS2 on Windows 7 with Mingw64 compiler.
terminate called after throwing an instance of 'tacopie::tacopie_error'
what(): fail socket()
That's the TCP server example copied and pasted. The issue is in the tcp_server constructor.
hi,
I have used your cpp_redis, in your source code, i see you have implemented a lightweight thread pool,
I wonder why you has not lock the m_nb_runing_threads variable to protect it from race condition?
each thread of the worker pool would execute the following code:
//
if (should_stop()) {
//may occur the race condition
--m_nb_running_threads;
return {true, nullptr};
}
bool
thread_pool::should_stop(void) const {
return m_should_stop || m_nb_running_threads > m_max_nb_threads;
}
//
would you like to give me an explanation?I am a little confused of it, thank you very much.
Issue imported from emails:
Bonjour Simon,
ça va?
I'm very happy to have discovered your excellent Tacopie library on GitHub. You know, I was looking for a modern TCP server library that would take a lot of work out of my hands. I'm currently using it in order to run a few custom VNC-server experiments.
However, I now think I have run into a bug (either in my own program, tacopie or perhaps both).
Background:
I have made a small tacopie based "VNC server" program that talks to the well known "Ultra VNC Viewer" / "Tight VNC viewer" etc.
Now the current implementation of "my" VNC server is minimalistic.
For instance it does not send 'incremental' screen updates at all (yet).
Build-up
When I connect with the UVNC client, the connection is established fine and things generally work as expected. UVNC displays the screen I'm sending and receiving keyboard/mouse input works too. Life is good!
Remember I don't send incremental updates to UVNC. Well, at some point in time, UVNC starts to worry about that and decides that it now has waited long enough for those. It then simply stops receiving data from its socket and displays a (misleading!) "server closed the connection" popup.
And I know it is misleading because all the while its TCP socket is actually still open! I verified this with Wireshark: no FIN messages etc.
To further convince myself the connection is still open I press the "refresh screen" button on the UVNC toolbar a few times. The server 'sees' these update requests and duly replies, writing a lot of data to the socket.
Since UVNC is not receiving data from the socket, this causes a so called "TCP zero window" situation where basically the TCP-buffer on the client side is exhausted.
Here comes the real problem
If I dismiss the UVNC popup under these specific conditions, the TCP connection will actually be terminated (which is good). But the server application may now crash with an access violation.
The crash happens when trying to obtain the mutex m_write_requests_mtx inside method tcp_client::process_write. I suspect the tcp_client object is destroyed before process_write is called.
The more bytes I attempt to write in that zero window situation, the higher the chance the server application will crash this way. If I press that refresh button numerous times, the crash is virtually guaranteed.
I figure this has something to do with those bytes that could not be written to the socket, delivered etc.
It looks to me like a race condition where part of the library wants to notify the connection object after having it already destroyed somewhere else (from another thread?).
Disclaimer: I'm not sure if this can be attributed to a bug in my program or the library, but I thought I would communicate it anyway... It may or may not be of help to you.
I'd like to send msg from server to client, not just received from client then reply.
Is there any way to do these? I cant find any write function in tcp_server.cpp.
I delete some code from demo, then my client can't receive any msg anymore.
like this:
Work well
void on_new_message(const std::shared_ptrtacopie::tcp_client& client, const tacopie::tcp_client::read_result& res) {
if (res.success) {
std::cout << "Client recv data" << std::endl;
client->async_write({ res.buffer, nullptr });
client->async_read({ 1024, std::bind(&on_new_message, client, std::placeholders::_1) });
}
else {
std::cout << "Client disconnected" << std::endl;
client->disconnect();
}
}
** "Client recv data" shown, client got no reply **
void on_new_message(const std::shared_ptrtacopie::tcp_client& client, const tacopie::tcp_client::read_result& res) {
if (res.success) {
std::cout << "Client recv data" << std::endl;
client->async_write({ res.buffer, nullptr });
// client->async_read({ 1024, std::bind(&on_new_message, client, std::placeholders::_1) });
}
else {
std::cout << "Client disconnected" << std::endl;
client->disconnect();
}
}
I am not sure its a bug or i made some mistake.
Clang analyzer shows this error:
Logic error: Branch condition evaluates to a garbage value
1: Calling 'tcp_client::process_write' in tacopie/sources/network/tcp_client.cpp:174
2: Assuming the condition is true in tacopie/sources/network/tcp_client.cpp:218
3: Returning from 'tcp_client::process_write' in tacopie/sources/network/tcp_client.cpp:174
4: Branch condition evaluates to a garbage value in tacopie/sources/network/tcp_client.cpp:176
The value result.success
seems never to be initialized anywhere here:
read_result result;
auto callback = process_read(result);
if (!result.success) {
__TACOPIE_LOG(warn, "read operation failure");
disconnect();
}
While I see that process_read() does the initialization, I'm wondering whether there's something else missing.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.