rioring
Update 0.2.1
https://github.com/newbiediver/rioring
C++17 跨平台非同步網路 I/O 函式庫。
C++17 跨平台非同步網路 I/O 函式庫。
我們使用適用於 Windows 和 Linux 平台的最新模型。
該庫使用 Windows 和 Linux 平台上可用的最新模型。
Windows平台上使用Registered i/o作為基本模型,Linux平台上使用io_uring。
Windows 平台上預設模型為 Registered i/o,Linux 平台上預設模型為 io_uring。
此 I/O 庫僅支援內建套接字物件。不支援文件描述符。
此 i/o 庫僅支援內建套接字物件。不支援文件描述符。
注意:貢獻者應該在 dev 分支上請求 PR。貢獻者政策將很快更新。
注意:請貢獻者向開發分支請求 PR。我們將盡快更新貢獻者政策。
注意:我還沒有測試 clang 編譯器。
注意:clang 編譯器尚未經過測試。
Minumum - MSVC 16.0 (Visual Studio 2019)
Recommend - MSVC 17.0 (Visual Studio 2022)
Minumum - gcc 9
Recommend - gcc 11
x64/amd64
* Windows
- >= Windows 8, Windows Server 2012 SP3
* Linux
- >= Kernel 5.13
- >= liburing 2.1 (Ex> Installable 2.1 on ubuntu apt)
Registered I/O - Windows platform
I/O Uring - Linux platform
TCP - Socket and server system
UDP - Socket and server system
Thread generator - Generate thread wrapper
Thread object - Thread as a object
Safe unlimited buffer - Never overflow buffer
Double buffer - Switchable unlimited buffer
Built-in address resolver
Etc...
# 소스코드 클론
# Clone source code
C: d ev > git clone https://github.com/newbiediver/rioring.git ./source
# 빌드
# Build
C: y our p ath > cd source
C: y our p ath s ource > cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=C:/your/path/rioring -B . b uild
C: y our p ath s ource > cmake --build . b uild
# 설치
# Install
C: y our p ath s ource > cmake --install . b uild s rc
# C:yourpathrioringinclude <-- header files path
# C:yourpathrioringlib <-- library file path
# liburing 라이브러리 설치
# Install liburing library (Ex> Debian/Ubuntu)
~ /your/path $ sudo apt install -y liburing-dev
# 소스코드 클론
# Clone source code
~ /your/path $ git clone https://github.com/newbiediver/rioring.git ./source
# 빌드
# Build
~ /your/path $ cd source
~ /your/path/source $ cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local -B ./build
~ /your/path/source $ cmake --build ./build
# 설치
# Install
~ /your/path/source $ sudo cmake --install ./build/src
# /usr/local/include <-- header files path
# /usr/local/lib <-- library file path
# include < iostream >
# include < unordered_set >
# include < rioring.h >
using namespace rioring ;
using namespace std ::chrono_literals ;
class event_receiver {
public:
event_receiver () = default ;
~event_receiver () = default ;
void on_accept_client ( tcp_socket_ptr &new_socket ) {
// register events for new socket at this time.
// Normally receive and close events and or error event.
// If you need sending completion event, you can also register 'set_send_complete_event'.
new_socket-> set_close_event ( [event = this ]( auto && socket ) {
event-> on_disconnect_client ( std::forward< decltype ( socket ) >( socket ) );
} );
new_socket-> set_receive_event ( []( auto &&socket, auto &&buffer, auto &&addr ) {
event_receiver::on_read_message ( std::forward< decltype ( socket ) >( socket ),
std::forward< decltype ( buffer ) >( buffer ),
std::forward< decltype ( addr ) >( addr ) );
} );
std::cout << " Connected client " << new_socket-> remote_ipv4 () << " : " << new_socket-> remote_port () << std::endl;
std::scoped_lock sc{ container_lock };
activating_sockets. insert ( new_socket );
}
static void on_read_message ( socket_ptr &socket, io_buffer *buffer, sockaddr *addr [[maybe_unused]] ) {
// just echo
auto tcp = to_tcp_socket_ptr ( socket );
tcp-> send ( *(*buffer), buffer-> size () );
// pop contents from buffer
buffer-> pop ( buffer-> size () );
}
void on_disconnect_client ( socket_ptr &socket ) {
std::cout << " Disconnect client " << socket-> remote_ipv4 () << " : " << socket-> remote_port () << std::endl;
std::scoped_lock sc{ container_lock };
activating_sockets. erase ( socket );
}
void leave_clients () {
std::scoped_lock sc{ container_lock };
for ( auto & socket : activating_sockets ) {
auto tcp = to_tcp_socket_ptr ( socket );
tcp-> close ();
}
}
void wait () const {
while ( !activating_sockets. empty () ) {
std::this_thread::sleep_for ( 1ms );
}
}
critical_section container_lock;
std::unordered_set< socket_ptr > activating_sockets;
};
int main () {
constexpr unsigned short port = 8000 ;
event_receiver receiver;
std::string in;
// Initialize i/o service.
io_service io;
if ( !io. run ( static_cast < int >( std::thread::hardware_concurrency () ) ) ) {
std::cerr << " failed to run io service " << std::endl;
return 1 ;
}
std::cout << " started io service " << std::endl;
// Initialize tcp listener.
tcp_server_ptr server = tcp_server::create ( &io );
if ( !server ) {
std::cerr << " failed to create server object " << std::endl;
return 1 ;
}
// accept event.
server-> set_accept_event ( [event = &receiver]( auto && new_socket ) {
event-> on_accept_client ( std::forward< decltype ( new_socket )>( new_socket ) );
} );
// run this server.
if ( !server-> run ( port ) ) {
std::cerr << " failed to open server port " << std::endl;
return 1 ;
}
std::cout << " started server. port: " << port << std::endl;
std::cout << " Enter 'exit' to terminate server " << std::endl;
while ( true ) {
std::cin >> in;
if ( in == " exit " ) {
break ;
}
}
receiver. leave_clients ();
receiver. wait ();
server-> stop ();
io. stop ();
return 0 ;
}
# cmake g++-11 ninja-build included
# you can use rioring include & rioring.a library file
FROM ghcr.io/newbiediver/rioring:latest
...
麻省理工學院許可證 版權所有 (c) 2022 NewbieDiver