src/​examples/​cpp03/​local/​connect_pair.​cppsrc/​examples/​cpp11/​local/​connect_pair.​cpp
1 /​/​1 /​/​
2 /​/​·​connect_pair.​cpp2 /​/​·​connect_pair.​cpp
3 /​/​·​~~~~~~~~~~~~~~~~3 /​/​·​~~~~~~~~~~~~~~~~
4 /​/​4 /​/​
5 /​/​·​Copyright·​(c)​·​2003-​2022·​Christopher·​M.​·​Kohlhoff·​(chris·​at·​kohlhoff·​dot·​com)​5 /​/​·​Copyright·​(c)​·​2003-​2022·​Christopher·​M.​·​Kohlhoff·​(chris·​at·​kohlhoff·​dot·​com)​
6 /​/​6 /​/​
7 /​/​·​Distributed·​under·​the·​Boost·​Software·​License,​·​Version·​1.​0.​·​(See·​accompanying7 /​/​·​Distributed·​under·​the·​Boost·​Software·​License,​·​Version·​1.​0.​·​(See·​accompanying
8 /​/​·​file·​LICENSE_1_0.​txt·​or·​copy·​at·​http:​/​/​www.​boost.​org/​LICENSE_1_0.​txt)​8 /​/​·​file·​LICENSE_1_0.​txt·​or·​copy·​at·​http:​/​/​www.​boost.​org/​LICENSE_1_0.​txt)​
9 /​/​9 /​/​
10 10
11 #include·​<array>
11 #include·​<iostream>12 #include·​<iostream>
12 #include·​<string>13 #include·​<string>
13 #include·​<cctype>14 #include·​<cctype>
14 #include·​<asio.​hpp>15 #include·​<asio.​hpp>
15 #include·​<boost/​array.​hpp>
16 #include·​<boost/​bind/​bind.​hpp>
17 16
18 #if·​defined(ASIO_HAS_LOCA​L_SOCKETS)​17 #if·​defined(ASIO_HAS_LOCA​L_SOCKETS)​
19 18
20 using·​asio:​:​local:​:​stream_protocol;​19 using·​asio:​:​local:​:​stream_protocol;​
21 20
22 class·​uppercase_filter21 class·​uppercase_filter
23 {22 {
24 public:​23 public:​
25 ··​uppercase_filter(asio​:​:​io_context&·io_context)​24 ··​uppercase_filter(stre​am_protocol:​:​socket·sock)​
26 ····​:​·​socket_(io_context)​25 ····​:​·​socket_(std:​:​move(sock)​)​
27 ··​{26 ··​{
28 ··}27 ····read()​;​
29
30 ··stream_protocol:​:​socket&·socket()​
31 ··{
32 ····return·socket_;​
33 ··}
34
35 ··void·start()​
36 ··{
37 ····/​/​·Wait·for·request.​
38 ····socket_.​async_read_some(asio:​:​buffer(data_)​,​
39 ········boost:​:​bind(&uppercase_filte​r:​:​handle_read,​
40 ··········this,​·asio:​:​placeholders:​:​error,​
41 ··········asio:​:​placeholders:​:​bytes_transferred)​)​;​
42 ··​}28 ··​}
43 29
44 private:​30 private:​
45 ··​void·handle_read(const·asio:​:​error_code&·ec,​·std:​:​size_t·size)​31 ··​void·​read()​
46 ··​{32 ··​{
47 ····​if·(!ec)​33 ····socket_.​async_read_some(asio:​:​buffer(data_)​,​
48 ····{34 ········[this](std:​:​error_code·ec,​·std:​:​size_t·size)​
49 ······/​/​·Compute·result.​35 ········{
50 ······for·(std:​:​size_t·i·=·0;​·​i·<·size;​·++i)​36 ··········​if·(!ec)​
51 ········data_[i]·=·std:​:​toupper(data_[i])​;​37 ··········{
52 38 ············/​/​·Compute·result.​
53 ······/​/​·Send·result.​39 ············for·(std:​:​size_t·i·=·0;​·i·<·size;​·++i)​
54 ······asio:​:​async_write(socket_,​·asio:​:​buffer(data_,​·size)​,​40 ··············data_[i]·=·​std:​:​toupper(data_[i])​;​
55 ··········boost:​:​bind(&uppercase_filte​r:​:​handle_write,​41
56 ············this,​·asio:​:​placeholders:​:​error)​)​;​42 ············/​/​·Send·result.​
57 ····}43 ············write(size)​;​
58 ····else44 ··········}
59 ····{45 ··········else
60 ······throw·asio:​:​system_error(ec)​;​46 ··········{
61 ····}47 ············throw·asio:​:​system_error(ec)​;​
62 ··​}48 ··········​}
63 49 ········})​;​
64 ··void·handle_write(const·asio:​:​error_code&·ec)​50 ··}
65 ··{51
66 ····if·(!ec)​52 ··void·write(std:​:​size_t·size)​
67 ····​{53 ··​{
68 ······/​/​·Wait·for·request.​54 ····asio:​:​async_write(socket_,​·asio:​:​buffer(data_,​·size)​,​
69 ······socket_.​async_read_some(asio:​:​buffer(data_)​,​55 ········[this](std:​:​error_code·ec,​·std:​:​size_t·/​*size*/​)​
70 ··········boost:​:​bind(&uppercase_filte​r:​:​handle_read,​56 ········{
71 ············this,​·asio:​:​placeholders:​:​error,​57 ··········​if·(!ec)​
72 ············asio:​:​placeholders:​:​bytes_transferred)​)​;​58 ··········{
73 ····}59 ············/​/​·Wait·for·request.​
74 ····​else60 ············read()​;​
75 ····{61 ··········}
76 ······throw·asio:​:​system_error(ec)​;​62 ··········else
77 ····}63 ··········{
64 ············​throw·​asio:​:​system_error(ec)​;​
65 ··········​}
66 ········​})​;​
78 ··​}67 ··​}
79 68
80 ··​stream_protocol:​:​socket·​socket_;​69 ··​stream_protocol:​:​socket·​socket_;​
81 ··boost:​:​array<char,​·​512>·​data_;​70 ··​std:​:​array<char,​·​512>·​data_;​
82 };​71 };​
83 72
84 void·​run(asio:​:​io_context*·​io_context)​
85 {
86 ··​try
87 ··​{
88 ····​io_context-​>run()​;​
89 ··​}
90 ··​catch·​(std:​:​exception&·​e)​
91 ··​{
92 ····​std:​:​cerr·​<<·​"Exception·​in·​thread:​·​"·​<<·​e.​what()​·​<<·​"\n";​
93 ····​std:​:​exit(1)​;​
94 ··​}
95 }
96
97 int·​main()​73 int·​main()​
98 {74 {
99 ··​try75 ··​try
100 ··​{76 ··​{
101 ····​asio:​:​io_context·​io_context;​77 ····​asio:​:​io_context·​io_context;​
102 78
103 ····​/​/​·​Create·filter·​and·establish·a·connection·to·it.​79 ····​/​/​·​Create·a·connected·pair·and·pass·one·end·to·a·filter.​
104 ····uppercase_filter·filter(io_context)​;​
105 ····​stream_protocol:​:​socket·​socket(io_context)​;​80 ····​stream_protocol:​:​socket·​socket(io_context)​;​
106 ····asio:​:​local:​:​connect_pair(socket,​·​filter.​socket()​)​;​81 ····​stream_protocol:​:​socket·​filter_socket(io_cont​ext)​;​
107 ····​filter.​start()​;​82 ····asio:​:​local:​:​connect_pair(socket,​·​filter_socket)​;​
83 ····​uppercase_filter·​filter(std:​:​move(filter_socket)​)​;​
108 84
109 ····​/​/​·​The·​io_context·​runs·​in·​a·​background·​thread·​to·​perform·​filtering.​85 ····​/​/​·​The·​io_context·​runs·​in·​a·​background·​thread·​to·​perform·​filtering.​
110 ····​asio:​:​thread·​thread(boost:​:​bind(run,​·&io_context)​)​;​86 ····​asio:​:​thread·​thread(
87 ········​[&io_context]()​
88 ········​{
89 ··········​try
90 ··········​{
91 ············​io_context.​run()​;​
92 ··········​}
93 ··········​catch·​(std:​:​exception&·​e)​
94 ··········​{
95 ············​std:​:​cerr·​<<·​"Exception·​in·​thread:​·​"·​<<·​e.​what()​·​<<·​"\n";​
96 ············​std:​:​exit(1)​;​
97 ··········​}
98 ········​})​;​
111 99
112 ····​for·​(;​;​)​100 ····​for·​(;​;​)​
113 ····​{101 ····​{
114 ······​/​/​·​Collect·​request·​from·​user.​102 ······​/​/​·​Collect·​request·​from·​user.​
115 ······​std:​:​cout·​<<·​"Enter·​a·​string:​·​";​103 ······​std:​:​cout·​<<·​"Enter·​a·​string:​·​";​
116 ······​std:​:​string·​request;​104 ······​std:​:​string·​request;​
117 ······​std:​:​getline(std:​:​cin,​·​request)​;​105 ······​std:​:​getline(std:​:​cin,​·​request)​;​
118 106
119 ······​/​/​·​Send·​request·​to·​filter.​107 ······​/​/​·​Send·​request·​to·​filter.​
120 ······​asio:​:​write(socket,​·​asio:​:​buffer(request)​)​;​108 ······​asio:​:​write(socket,​·​asio:​:​buffer(request)​)​;​
121 109
122 ······​/​/​·​Wait·​for·​reply·​from·​filter.​110 ······​/​/​·​Wait·​for·​reply·​from·​filter.​
123 ······​std:​:​vector<char>·​reply(request.​size()​)​;​111 ······​std:​:​vector<char>·​reply(request.​size()​)​;​
124 ······​asio:​:​read(socket,​·​asio:​:​buffer(reply)​)​;​112 ······​asio:​:​read(socket,​·​asio:​:​buffer(reply)​)​;​
125 113
126 ······​/​/​·​Show·​reply·​to·​user.​114 ······​/​/​·​Show·​reply·​to·​user.​
127 ······​std:​:​cout·​<<·​"Result:​·​";​115 ······​std:​:​cout·​<<·​"Result:​·​";​
128 ······​std:​:​cout.​write(&reply[0],​·​request.​size()​)​;​116 ······​std:​:​cout.​write(&reply[0],​·​request.​size()​)​;​
129 ······​std:​:​cout·​<<·​std:​:​endl;​117 ······​std:​:​cout·​<<·​std:​:​endl;​
130 ····​}118 ····​}
131 ··​}119 ··​}
132 ··​catch·​(std:​:​exception&·​e)​120 ··​catch·​(std:​:​exception&·​e)​
133 ··​{121 ··​{
134 ····​std:​:​cerr·​<<·​"Exception:​·​"·​<<·​e.​what()​·​<<·​"\n";​122 ····​std:​:​cerr·​<<·​"Exception:​·​"·​<<·​e.​what()​·​<<·​"\n";​
135 ····​std:​:​exit(1)​;​123 ····​std:​:​exit(1)​;​
136 ··​}124 ··​}
137 }125 }
138 126
139 #else·​/​/​·​defined(ASIO_HAS_LOCA​L_SOCKETS)​127 #else·​/​/​·​defined(ASIO_HAS_LOCA​L_SOCKETS)​
140 #·​error·​Local·​sockets·​not·​available·​on·​this·​platform.​128 #·​error·​Local·​sockets·​not·​available·​on·​this·​platform.​
141 #endif·​/​/​·​defined(ASIO_HAS_LOCA​L_SOCKETS)​129 #endif·​/​/​·​defined(ASIO_HAS_LOCA​L_SOCKETS)​