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 | #include <QtNetwork> |
29 | |
30 | class ClientServer : public QUdpSocket |
31 | { |
32 | Q_OBJECT |
33 | public: |
34 | enum Type { |
35 | ConnectedClient, |
36 | UnconnectedClient, |
37 | Server |
38 | }; |
39 | |
40 | ClientServer(Type type, const QString &host, quint16 port) |
41 | : type(type) |
42 | { |
43 | switch (type) { |
44 | case Server: |
45 | if (bind(port: 0, mode: ShareAddress | ReuseAddressHint)) { |
46 | printf(format: "%d\n" , localPort()); |
47 | } else { |
48 | printf(format: "XXX\n" ); |
49 | } |
50 | break; |
51 | case ConnectedClient: |
52 | connectToHost(hostName: host, port); |
53 | startTimer(interval: 250); |
54 | printf(format: "ok\n" ); |
55 | break; |
56 | case UnconnectedClient: |
57 | peerAddress = QHostAddress(host); |
58 | peerPort = port; |
59 | if (bind(address: QHostAddress::Any, port: port + 1, mode: ShareAddress | ReuseAddressHint)) { |
60 | startTimer(interval: 250); |
61 | printf(format: "ok\n" ); |
62 | } else { |
63 | printf(format: "XXX\n" ); |
64 | } |
65 | break; |
66 | } |
67 | fflush(stdout); |
68 | |
69 | connect(sender: this, SIGNAL(readyRead()), receiver: this, SLOT(readTestData())); |
70 | } |
71 | |
72 | protected: |
73 | void timerEvent(QTimerEvent *event) |
74 | { |
75 | static int n = 0; |
76 | switch (type) { |
77 | case ConnectedClient: |
78 | write(data: QByteArray::number(n++)); |
79 | break; |
80 | case UnconnectedClient: |
81 | writeDatagram(datagram: QByteArray::number(n++), host: peerAddress, port: peerPort); |
82 | break; |
83 | default: |
84 | break; |
85 | } |
86 | |
87 | QUdpSocket::timerEvent(event); |
88 | } |
89 | |
90 | private slots: |
91 | void readTestData() |
92 | { |
93 | printf(format: "readData()\n" ); |
94 | switch (type) { |
95 | case ConnectedClient: { |
96 | while (bytesAvailable() || hasPendingDatagrams()) { |
97 | QByteArray data = readAll(); |
98 | printf(format: "got %d\n" , data.toInt()); |
99 | } |
100 | break; |
101 | } |
102 | case UnconnectedClient: { |
103 | while (hasPendingDatagrams()) { |
104 | QByteArray data; |
105 | data.resize(size: pendingDatagramSize()); |
106 | readDatagram(data: data.data(), maxlen: data.size()); |
107 | printf(format: "got %d\n" , data.toInt()); |
108 | } |
109 | break; |
110 | } |
111 | case Server: { |
112 | while (hasPendingDatagrams()) { |
113 | QHostAddress sender; |
114 | quint16 senderPort; |
115 | QByteArray data; |
116 | data.resize(size: pendingDatagramSize()); |
117 | readDatagram(data: data.data(), maxlen: data.size(), host: &sender, port: &senderPort); |
118 | printf(format: "got %d\n" , data.toInt()); |
119 | printf(format: "sending %d\n" , data.toInt() * 2); |
120 | writeDatagram(datagram: QByteArray::number(data.toInt() * 2), host: sender, port: senderPort); |
121 | } |
122 | break; |
123 | } |
124 | } |
125 | fflush(stdout); |
126 | } |
127 | |
128 | private: |
129 | Type type; |
130 | QHostAddress peerAddress; |
131 | quint16 peerPort; |
132 | }; |
133 | |
134 | int main(int argc, char **argv) |
135 | { |
136 | QCoreApplication app(argc, argv); |
137 | ClientServer::Type type; |
138 | if (app.arguments().size() < 4) { |
139 | qDebug(msg: "usage: %s [ConnectedClient <server> <port>|UnconnectedClient <server> <port>|Server]" , argv[0]); |
140 | return 1; |
141 | } |
142 | |
143 | QString arg = app.arguments().at(i: 1).trimmed().toLower(); |
144 | if (arg == "connectedclient" ) { |
145 | type = ClientServer::ConnectedClient; |
146 | } else if (arg == "unconnectedclient" ) { |
147 | type = ClientServer::UnconnectedClient; |
148 | } else if (arg == "server" ) { |
149 | type = ClientServer::Server; |
150 | } else { |
151 | qDebug(msg: "usage: %s [ConnectedClient <server> <port>|UnconnectedClient <server> <port>|Server]" , argv[0]); |
152 | return 1; |
153 | } |
154 | |
155 | ClientServer clientServer(type, app.arguments().at(i: 2), |
156 | app.arguments().at(i: 3).toInt()); |
157 | |
158 | return app.exec(); |
159 | } |
160 | |
161 | #include "main.moc" |
162 | |