1 | #include <sys/types.h> |
2 | #include <sys/socket.h> |
3 | #include <unistd.h> |
4 | |
5 | #include <iostream> |
6 | #include <Poco/Net/StreamSocket.h> |
7 | #include <Common/Exception.h> |
8 | #include <IO/ReadHelpers.h> |
9 | |
10 | |
11 | /** In a loop it connects to the server and immediately breaks the connection. |
12 | * Using the SO_LINGER option, we ensure that the connection is terminated by sending a RST packet (not FIN). |
13 | * This behavior causes a bug in the TCPServer implementation in the Poco library. |
14 | */ |
15 | int main(int argc, char ** argv) |
16 | try |
17 | { |
18 | for (size_t i = 0, num_iters = argc >= 2 ? DB::parse<size_t>(argv[1]) : 1; i < num_iters; ++i) |
19 | { |
20 | std::cerr << "." ; |
21 | |
22 | Poco::Net::SocketAddress address("localhost" , 9000); |
23 | |
24 | int fd = socket(PF_INET, SOCK_STREAM, IPPROTO_IP); |
25 | |
26 | if (fd < 0) |
27 | DB::throwFromErrno("Cannot create socket" , 0); |
28 | |
29 | linger linger_value; |
30 | linger_value.l_onoff = 1; |
31 | linger_value.l_linger = 0; |
32 | |
33 | if (0 != setsockopt(fd, SOL_SOCKET, SO_LINGER, &linger_value, sizeof(linger_value))) |
34 | DB::throwFromErrno("Cannot set linger" , 0); |
35 | |
36 | try |
37 | { |
38 | int res = connect(fd, address.addr(), address.length()); |
39 | |
40 | if (res != 0 && errno != EINPROGRESS && errno != EWOULDBLOCK) |
41 | { |
42 | close(fd); |
43 | DB::throwFromErrno("Cannot connect" , 0); |
44 | } |
45 | |
46 | close(fd); |
47 | } |
48 | catch (const Poco::Exception & e) |
49 | { |
50 | std::cerr << e.displayText() << "\n" ; |
51 | } |
52 | } |
53 | |
54 | std::cerr << "\n" ; |
55 | } |
56 | catch (const Poco::Exception & e) |
57 | { |
58 | std::cerr << e.displayText() << "\n" ; |
59 | } |
60 | |