1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the test suite of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU |
19 | ** General Public License version 3 as published by the Free Software |
20 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT |
21 | ** included in the packaging of this file. Please review the following |
22 | ** information to ensure the GNU General Public License requirements will |
23 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. |
24 | ** |
25 | ** $QT_END_LICENSE$ |
26 | ** |
27 | ****************************************************************************/ |
28 | |
29 | |
30 | #include <qcoreapplication.h> |
31 | #include <qelapsedtimer.h> |
32 | #include <qeventloop.h> |
33 | #include <qlocalsocket.h> |
34 | #include <qlocalserver.h> |
35 | #include <qtimer.h> |
36 | |
37 | const QString serverName = QStringLiteral("qlocalsocket_autotest" ); |
38 | const QByteArray testData("test" ); |
39 | |
40 | bool runServer(int numberOfConnections) |
41 | { |
42 | QLocalServer *server = new QLocalServer(qApp); |
43 | if (!server->removeServer(name: serverName)) { |
44 | fprintf(stderr, format: "server: cannot remove server: %s\n" , qPrintable(server->errorString())); |
45 | return false; |
46 | } |
47 | printf(format: "server: listen on \"%s\"\n" , qPrintable(serverName)); |
48 | if (!server->listen(name: serverName)) { |
49 | fprintf(stderr, format: "server: listen failed: %s\n" , qPrintable(server->errorString())); |
50 | return false; |
51 | } |
52 | for (int i = 1; i <= numberOfConnections; ++i) { |
53 | printf(format: "server: wait for connection %d\n" , i); |
54 | if (!server->waitForNewConnection(msec: 30000)) { |
55 | fprintf(stderr, format: "server: waitForNewConnection failed: %s\n" , |
56 | qPrintable(server->errorString())); |
57 | return false; |
58 | } |
59 | QLocalSocket *socket = server->nextPendingConnection(); |
60 | printf(format: "server: writing \"%s\"\n" , testData.data()); |
61 | socket->write(data: testData); |
62 | if (!socket->waitForBytesWritten()) { |
63 | fprintf(stderr, format: "server: waitForBytesWritten failed: %s\n" , |
64 | qPrintable(socket->errorString())); |
65 | return false; |
66 | } |
67 | printf(format: "server: data written\n" ); |
68 | if (socket->error() != QLocalSocket::UnknownSocketError) { |
69 | fprintf(stderr, format: "server: socket error %d\n" , socket->error()); |
70 | return false; |
71 | } |
72 | } |
73 | return true; |
74 | } |
75 | |
76 | bool runClient() |
77 | { |
78 | QLocalSocket socket; |
79 | printf(format: "client: connecting to \"%s\"\n" , qPrintable(serverName)); |
80 | QElapsedTimer connectTimer; |
81 | connectTimer.start(); |
82 | forever { |
83 | socket.connectToServer(name: serverName, openMode: QLocalSocket::ReadWrite); |
84 | if (socket.waitForConnected()) |
85 | break; |
86 | if (socket.error() == QLocalSocket::ServerNotFoundError |
87 | || socket.error() == QLocalSocket::ConnectionRefusedError) { |
88 | if (connectTimer.elapsed() > 5000) { |
89 | fprintf(stderr, format: "client: server not found or connection refused. Giving up.\n" ); |
90 | return false; |
91 | } |
92 | printf(format: "client: server not found. Trying again...\n" ); |
93 | QEventLoop eventLoop; |
94 | QTimer::singleShot(msec: 500, receiver: &eventLoop, SLOT(quit())); |
95 | eventLoop.exec(); |
96 | continue; |
97 | } |
98 | fprintf(stderr, format: "client: waitForConnected failed: %s\n" , |
99 | qPrintable(socket.errorString())); |
100 | return false; |
101 | } |
102 | printf(format: "client: connected\n" ); |
103 | if (!socket.waitForReadyRead()) { |
104 | fprintf(stderr, format: "client: waitForReadyRead failed: %s\n" , |
105 | qPrintable(socket.errorString())); |
106 | return false; |
107 | } |
108 | printf(format: "client: data is available for reading\n" ); |
109 | const QByteArray data = socket.readLine(); |
110 | printf(format: "client: received \"%s\"\n" , data.data()); |
111 | if (data != testData) { |
112 | fprintf(stderr, format: "client: received unexpected data\n" ); |
113 | return false; |
114 | } |
115 | return true; |
116 | } |
117 | |
118 | int main(int argc, char **argv) |
119 | { |
120 | QCoreApplication app(argc, argv); |
121 | if (argc < 2) |
122 | return EXIT_FAILURE; |
123 | if (strcmp(s1: argv[1], s2: "--server" ) == 0) { |
124 | if (argc < 3) { |
125 | fprintf(stderr, format: "--server needs the number of incoming connections\n" ); |
126 | return EXIT_FAILURE; |
127 | } |
128 | bool ok; |
129 | int n = QByteArray(argv[2]).toInt(ok: &ok); |
130 | if (!ok) { |
131 | fprintf(stderr, format: "Cannot convert %s to a number.\n" , argv[2]); |
132 | return EXIT_FAILURE; |
133 | } |
134 | if (!runServer(numberOfConnections: n)) |
135 | return EXIT_FAILURE; |
136 | } else if (strcmp(s1: argv[1], s2: "--client" ) == 0) { |
137 | if (!runClient()) |
138 | return EXIT_FAILURE; |
139 | } else { |
140 | fprintf(stderr, format: "unknown command line option: %s\n" , argv[1]); |
141 | return EXIT_FAILURE; |
142 | } |
143 | return EXIT_SUCCESS; |
144 | } |
145 | |