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 */
15int main(int argc, char ** argv)
16try
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}
56catch (const Poco::Exception & e)
57{
58 std::cerr << e.displayText() << "\n";
59}
60