-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathstream_client.cpp
148 lines (121 loc) · 3.42 KB
/
stream_client.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
//
// Copyright (c) 2023-present DeepGrace (complex dot invoke at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/deepgrace/snp
//
#define BOOST_ASIO_HAS_IO_URING
#define BOOST_ASIO_DISABLE_EPOLL
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <snp.hpp>
#include <unifex/then.hpp>
#include <unifex/upon_error.hpp>
// g++ -std=c++23 -Wall -O3 -Os -s -I include -l uring example/stream_client.cpp -o /tmp/stream_client
using namespace unifex;
namespace net = boost::asio;
using net::local::stream_protocol;
using socket_t = stream_protocol::socket;
using endpoint_t = stream_protocol::endpoint;
using error_code_t = boost::system::error_code;
constexpr std::size_t length = 1024;
class client
{
public:
client(net::io_context& ioc, const std::string& file) : socket(ioc), endpoints{endpoint_t(file)}
{
}
void run()
{
do_connect();
}
void do_connect()
{
snp::async_connect(socket, endpoints)
| unifex::then([this](endpoint_t ep)
{
on_connect();
})
| unifex::upon_error([]<typename Error>(Error error)
{
if constexpr(std::is_same_v<Error, error_code_t>)
std::cerr << "async_connect: " << error.message() << std::endl;
})
| snp::start_detached();
}
void on_connect()
{
do_write();
}
void do_write()
{
std::cout << "Enter message: ";
std::cin.getline(request, length);
size = std::strlen(request);
snp::async_write(socket, net::buffer(request, size))
| unifex::then([this](std::size_t bytes_transferred)
{
on_write();
})
| unifex::upon_error([]<typename Error>(Error error)
{
if constexpr(std::is_same_v<Error, error_code_t>)
std::cerr << "async_write: " << error.message() << std::endl;
})
| snp::start_detached();
}
void on_write()
{
do_read();
}
void do_read()
{
snp::async_read(socket, net::buffer(reply, size))
| unifex::then([this](std::size_t bytes_transferred)
{
on_read(bytes_transferred);
})
| unifex::upon_error([]<typename Error>(Error error)
{
if constexpr(std::is_same_v<Error, error_code_t>)
std::cerr << "async_read: " << error.message() << std::endl;
})
| snp::start_detached();
}
void on_read(std::size_t bytes_transferred)
{
std::cout << "Reply is: ";
std::cout.write(reply, bytes_transferred);
std::cout << std::endl;
}
private:
char request[length];
char reply[length];
socket_t socket;
std::size_t size;
std::vector<endpoint_t> endpoints;
};
int main(int argc, char* argv[])
{
try
{
if (argc != 2)
{
std::cerr << "Usage: " << argv[0] << " <file>" << std::endl;
std::cerr << "Example: " << argv[0] << " /tmp/sock" << std::endl;
return 1;
}
net::io_context ioc;
client c(ioc, argv[1]);
c.run();
ioc.run();
}
catch (std::exception& e)
{
std::cerr << "Exception: " << e.what() << std::endl;
}
return 0;
}