GithubHelp home page GithubHelp logo

cylix / tacopie Goto Github PK

View Code? Open in Web Editor NEW
375.0 26.0 129.0 1.03 MB

C++ TCP Library - NO LONGER MAINTAINED

License: MIT License

CMake 6.66% Shell 0.14% C++ 91.27% Python 1.92%
cpp cpp11 tcp tcp-client tcp-server no-dependencies

tacopie's Introduction

Important

Please be advised that this library is no longer maintained.

I have maintained this library for over 2 years, but I do not have enough time to provide a reliable support and continuous development for any longer.

Any existing or new issues will not be treated and I do not guarantee to merge any new pull request.

If anyone is willing to take over this project, feel free to fork this project and message me to add a link to your fork in this README.

Taco Pie Build Status Build status

tacopie is a multi-platform TCP Client & Server C++11 library.

Requirement

tacopie has no dependency. Its only requirement is C++11.

Example

tacopie::tcp_server:

tacopie::tcp_server s;
s.start("127.0.0.1", 3001, [] (const std::shared_ptr<tacopie::tcp_client>& client) -> bool {
  std::cout << "New client" << std::endl;
  return true;
});

tacopie::tcp_server full documentation and detailed example.

tacopie::tcp_client:

tacopie::tcp_client client;
client.connect("127.0.0.1", 3001);
client.async_read({ 1024, [&] (tacopie::tcp_client::read_result& res) {
  client.async_write({ res.buffer, nullptr });
} });

tacopie::tcp_client full documentation and detailed example.

Wiki

A Wiki is available and provides full documentation for the library as well as installation explanations.

Doxygen

A Doxygen documentation is available and provides full API documentation for the library.

License

tacopie is under MIT License.

Contributing

Please refer to CONTRIBUTING.md.

Author

Simon Ninon

tacopie's People

Contributors

cmorse avatar cylix avatar kevin1018 avatar meisenzahl avatar navossoc avatar ppietrasa avatar sandsmark avatar steple avatar thequantumphysicist avatar whtalpha avatar yuangu avatar zodiac403 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

tacopie's Issues

tacopie thread_pool class variable m_nb_running_threads should lock to avoid race condition?

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.

Running on vis. std. 2017

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,

How can I use the tacopie server to send a lot of messages?

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.

Tacopie TCP server library (read access violation after close under TCP zero window condition)

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.

Trying to serve html to browser on tacopie server

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();
		}
	}

Build dynamic library failed on Windows

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:

  • Use latest tacopie tag(3.1.0)
  • Change visual studio solution configure: Configuration Type: static to dynamic

Windows dynamic port range

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.

Conan package

Hello,
Do you know about Conan?
Conan is modern dependency manager for C++. And will be great if your library will be available via package manager for other developers.

Here you can find example, how you can create package for the library.

If you have any questions, just ask :-)

Inconsistent async_read behaviour after 2.4.3

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.

TCP Server example throws exception

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.

gethostbyname is thread unsafe

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,

Wiki possibly out of date for newest VS15 (2017)

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

tacopie::tcp_client::async_read returning before reading all bytes

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)

Include <functional>

[ 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>.

High CPU usage

io_service_diff.txt

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

Tacopie client: UDP?

  1. Does Tacopie client work with non-Tacopie servers ?
  2. I'd like to connect to GrayLog server and send log records in Gelf format
  3. I'd like to send UDP messages

Branch on a garbage value

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.

confusion about self_pipe

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?

Error when trying to connect to a wrong port

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

BAD

This is really a very good library if you remove the usage of c++ exception!!!!!!VERY BAD DESIGN

================================
terminate called after throwing an instance of 'tacopie::tacopie_error'
what(): getaddrinfo() failure
Press to close this window...

See...My app crashed just because I didn't use 'try...catch...'
If you follow Microsoft, you will dead in the end!

How to make a broadcast on tcp server?

Hey guy, thx for your great job.
Here is what i met

1 Send msg form server

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.

2 Bug

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.

if obj outputs to same path,will make error on the link.

严重性 代码 说明 项目 文件 行 禁止显示状态
警告 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

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.