Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qlocalsocket_tcp.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qlocalsocket.h"
5#include "qlocalsocket_p.h"
6#include "qlocalserver.h"
7
8#include <qhostaddress.h>
9#include <qsettings.h>
10#include <qdebug.h>
11
13
14using namespace Qt::StringLiterals;
15
17 tcpSocket(0),
18 ownsTcpSocket(true),
19 state(QLocalSocket::UnconnectedState)
20{
21}
22
24{
25 setSocket(new QLocalUnixSocket);
26}
27
28void QLocalSocketPrivate::setSocket(QLocalUnixSocket* socket)
29{
30 if (ownsTcpSocket)
31 delete tcpSocket;
32 ownsTcpSocket = false;
33 tcpSocket = socket;
34
35 Q_Q(QLocalSocket);
36 // QIODevice signals
37 q->connect(tcpSocket, SIGNAL(bytesWritten(qint64)),
39 q->connect(tcpSocket, SIGNAL(readyRead()), q, SIGNAL(readyRead()));
40 // QAbstractSocket signals
41 q->connect(tcpSocket, SIGNAL(connected()), q, SIGNAL(connected()));
42 q->connect(tcpSocket, SIGNAL(disconnected()), q, SIGNAL(disconnected()));
43 q->connect(tcpSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)),
45 q->connect(tcpSocket, SIGNAL(errorOccurred(QAbstractSocket::SocketError)),
47 q->connect(tcpSocket, SIGNAL(readChannelFinished()), q, SIGNAL(readChannelFinished()));
48 tcpSocket->setParent(q);
49}
50
52{
53 Q_Q(QLocalSocket);
54 QString function = "QLocalSocket"_L1;
57 q->setErrorString(errorString);
58 emit q->errorOccurred(error);
59}
60
62{
63 Q_Q(QLocalSocket);
65 switch(newState) {
70 break;
73 break;
76 break;
79 break;
80 default:
81#if defined QLOCALSOCKET_DEBUG
82 qWarning() << "QLocalSocket::Unhandled socket state change:" << newState;
83#endif
84 return;
85 }
86 if (currentState != state)
87 emit q->stateChanged(state);
88}
89
91{
93 switch (error) {
95 errorString = QLocalSocket::tr("%1: Connection refused").arg(function);
96 break;
98 errorString = QLocalSocket::tr("%1: Remote closed").arg(function);
99 break;
101 errorString = QLocalSocket::tr("%1: Invalid name").arg(function);
102 break;
104 errorString = QLocalSocket::tr("%1: Socket access error").arg(function);
105 break;
107 errorString = QLocalSocket::tr("%1: Socket resource error").arg(function);
108 break;
110 errorString = QLocalSocket::tr("%1: Socket operation timed out").arg(function);
111 break;
113 errorString = QLocalSocket::tr("%1: Datagram too large").arg(function);
114 break;
116 errorString = QLocalSocket::tr("%1: Connection error").arg(function);
117 break;
119 errorString = QLocalSocket::tr("%1: The socket operation is not supported").arg(function);
120 break;
122 errorString = QLocalSocket::tr("%1: Operation not permitted when socket is in this state").arg(function);
123 break;
125 default:
126 errorString = QLocalSocket::tr("%1: Unknown error").arg(function);
127 }
128 return errorString;
129}
130
132{
133 Q_Q(QLocalSocket);
134 switch (error) {
136 tcpSocket->setSocketError(QAbstractSocket::ConnectionRefusedError);
137 break;
139 tcpSocket->setSocketError(QAbstractSocket::RemoteHostClosedError);
140 break;
142 tcpSocket->setSocketError(QAbstractSocket::HostNotFoundError);
143 break;
145 tcpSocket->setSocketError(QAbstractSocket::SocketAccessError);
146 break;
148 tcpSocket->setSocketError(QAbstractSocket::SocketResourceError);
149 break;
151 tcpSocket->setSocketError(QAbstractSocket::SocketTimeoutError);
152 break;
154 tcpSocket->setSocketError(QAbstractSocket::DatagramTooLargeError);
155 break;
157 tcpSocket->setSocketError(QAbstractSocket::NetworkError);
158 break;
160 tcpSocket->setSocketError(QAbstractSocket::UnsupportedSocketOperationError);
161 break;
163 default:
164 tcpSocket->setSocketError(QAbstractSocket::UnknownSocketError);
165 }
166
168 q->setErrorString(errorString);
169 emit q->errorOccurred(error);
170
171 // errors cause a disconnect
172 tcpSocket->setSocketState(QAbstractSocket::UnconnectedState);
173 bool stateChanged = (state != QLocalSocket::UnconnectedState);
175 q->close();
176 if (stateChanged)
177 q->emit stateChanged(state);
178}
179
180void QLocalSocket::connectToServer(OpenMode openMode)
181{
182 Q_D(QLocalSocket);
183 if (state() == ConnectedState || state() == ConnectingState) {
184 setErrorString(tr("Trying to connect while connection is in progress"));
186 return;
187 }
188
189 d->errorString.clear();
190 d->state = ConnectingState;
191 emit stateChanged(d->state);
192
193 if (d->serverName.isEmpty()) {
194 d->setErrorAndEmit(ServerNotFoundError, "QLocalSocket::connectToServer"_L1);
195 return;
196 }
197
198 const auto prefix = "QLocalServer/"_L1;
199 if (d->serverName.startsWith(prefix))
200 d->fullServerName = d->serverName;
201 else
202 d->fullServerName = prefix + d->serverName;
203
204 QSettings settings("QtProject"_L1, "Qt"_L1);
205 bool ok;
206 const quint16 port = settings.value(d->fullServerName).toUInt(&ok);
207 if (!ok) {
208 d->setErrorAndEmit(ServerNotFoundError, "QLocalSocket::connectToServer"_L1);
209 return;
210 }
212 d->tcpSocket->connectToHost(QHostAddress::LocalHost, port, openMode);
213}
214
216 LocalSocketState socketState, OpenMode openMode)
217{
218 Q_D(QLocalSocket);
220 switch (socketState) {
221 case ConnectingState:
222 newSocketState = QAbstractSocket::ConnectingState;
223 break;
224 case ConnectedState:
225 newSocketState = QAbstractSocket::ConnectedState;
226 break;
227 case ClosingState:
228 newSocketState = QAbstractSocket::ClosingState;
229 break;
230 case UnconnectedState:
231 newSocketState = QAbstractSocket::UnconnectedState;
232 break;
233 }
235 d->state = socketState;
236
237 // Is our parent a localServer? Then it wants us to use its remote socket.
238 QLocalServer* localServer = qobject_cast<QLocalServer*>( parent() );
239 if (localServer) {
240 for (QObject* child : localServer->children()) {
241 QTcpSocket* childTcpSocket = qobject_cast<QTcpSocket*>(child);
242 if (childTcpSocket && childTcpSocket->socketDescriptor() == socketDescriptor) {
243 d->setSocket( static_cast<QLocalUnixSocket*>(childTcpSocket) );
244 return true;
245 }
246 }
247 }
248
249 // We couldn't find the socket in the children list of our server.
250 // So it might be that the user wants to set a socket descriptor.
251 return d->tcpSocket->setSocketDescriptor(socketDescriptor,
252 newSocketState, openMode);
253}
254
256{
257 Q_D(const QLocalSocket);
258 return d->tcpSocket->socketDescriptor();
259}
260
262{
263 Q_D(QLocalSocket);
264 return d->tcpSocket->read(data, c);
265}
266
268{
269 if (!maxSize)
270 return 0;
271
272 // QIODevice::readLine() reserves space for the trailing '\0' byte,
273 // so we must read 'maxSize + 1' bytes.
274 return d_func()->tcpSocket->readLine(data, maxSize + 1);
275}
276
278{
279 return d_func()->tcpSocket->skip(maxSize);
280}
281
283{
284 Q_D(QLocalSocket);
285 return d->tcpSocket->writeData(data, c);
286}
287
289{
290 Q_D(QLocalSocket);
291 d->tcpSocket->abort();
292 close();
293}
294
296{
297 Q_D(const QLocalSocket);
298 return QIODevice::bytesAvailable() + d->tcpSocket->bytesAvailable();
299}
300
302{
303 Q_D(const QLocalSocket);
304 return d->tcpSocket->bytesToWrite();
305}
306
308{
309 Q_D(const QLocalSocket);
310 return QIODevice::canReadLine() || d->tcpSocket->canReadLine();
311}
312
314{
315 Q_D(QLocalSocket);
316
318 d->tcpSocket->close();
319 d->serverName.clear();
320 d->fullServerName.clear();
321}
322
324{
325 Q_D(QLocalSocket);
326 return d->tcpSocket->waitForBytesWritten(msecs);
327}
328
330{
331 Q_D(QLocalSocket);
332 return d->tcpSocket->flush();
333}
334
336{
337 Q_D(QLocalSocket);
338 d->tcpSocket->disconnectFromHost();
339}
340
373
375{
376 Q_D(const QLocalSocket);
377 return d->tcpSocket->isValid();
378}
379
381{
382 Q_D(const QLocalSocket);
383 return d->tcpSocket->readBufferSize();
384}
385
387{
388 Q_D(QLocalSocket);
389 d->tcpSocket->setReadBufferSize(size);
390}
391
393{
394 Q_D(QLocalSocket);
395 if (state() != ConnectingState)
396 return (state() == ConnectedState);
397
398 return d->tcpSocket->waitForConnected(msec);
399}
400
402{
403 Q_D(QLocalSocket);
404 if (state() == UnconnectedState) {
405 qWarning("QLocalSocket::waitForDisconnected() is not allowed in UnconnectedState");
406 return false;
407 }
408 return (d->tcpSocket->waitForDisconnected(msecs));
409}
410
412{
413 Q_D(QLocalSocket);
415 return false;
416 return (d->tcpSocket->waitForReadyRead(msecs));
417}
418
bool connected
SocketState
This enum describes the different states in which a socket can be.
SocketError
This enum describes the socket errors that can occur.
virtual bool open(QIODeviceBase::OpenMode mode)
Opens the device and sets its OpenMode to mode.
void setErrorString(const QString &errorString)
Sets the human readable description of the last device error that occurred to str.
QIODeviceBase::OpenMode openMode() const
Returns the mode in which the device has been opened; i.e.
virtual qint64 bytesAvailable() const
Returns the number of bytes that are available for reading.
virtual void close()
First emits aboutToClose(), then closes the device and sets its OpenMode to NotOpen.
virtual bool canReadLine() const
Returns true if a complete line of data can be read from the device; otherwise returns false.
The QLocalServer class provides a local socket based server.
void _q_stateChanged(QAbstractSocket::SocketState newState)
QLocalSocket::LocalSocketState state
void _q_errorOccurred(QAbstractSocket::SocketError newError)
void setErrorAndEmit(QLocalSocket::LocalSocketError, const QString &function)
QString generateErrorString(QLocalSocket::LocalSocketError, const QString &function) const
The QLocalSocket class provides a local socket.
bool setSocketDescriptor(qintptr socketDescriptor, LocalSocketState socketState=ConnectedState, OpenMode openMode=ReadWrite)
Initializes QLocalSocket with the native socket descriptor socketDescriptor.
LocalSocketState state() const
Returns the state of the socket.
virtual qint64 readData(char *, qint64) override
\reimp
void abort()
Aborts the current connection and resets the socket.
virtual qint64 bytesToWrite() const override
\reimp
virtual bool canReadLine() const override
\reimp
bool waitForBytesWritten(int msecs=30000) override
\reimp
LocalSocketState
This enum describes the different states in which a socket can be.
bool isValid() const
Returns true if the socket is valid and ready for use; otherwise returns false.
bool flush()
This function writes as much as possible from the internal write buffer to the socket,...
LocalSocketError error() const
Returns the type of error that last occurred.
qint64 readBufferSize() const
Returns the size of the internal read buffer.
bool waitForDisconnected(int msecs=30000)
Waits until the socket has disconnected, up to msecs milliseconds.
void disconnectFromServer()
Attempts to close the socket.
qint64 readLineData(char *data, qint64 maxSize) override
\reimp
bool waitForConnected(int msecs=30000)
Waits until the socket is connected, up to msecs milliseconds.
bool waitForReadyRead(int msecs=30000) override
This function blocks until data is available for reading and the \l{QIODevice::}{readyRead()} signal ...
void connectToServer(OpenMode openMode=ReadWrite)
void setReadBufferSize(qint64 size)
Sets the size of QLocalSocket's internal read buffer to be size bytes.
qintptr socketDescriptor() const
Returns the native socket descriptor of the QLocalSocket object if this is available; otherwise retur...
virtual void close() override
Closes the I/O device for the socket and calls disconnectFromServer() to close the socket's connectio...
qint64 skipData(qint64 maxSize) override
\reimp
virtual qint64 bytesAvailable() const override
\reimp
void stateChanged(QLocalSocket::LocalSocketState socketState)
This signal is emitted whenever QLocalSocket's state changes.
virtual qint64 writeData(const char *, qint64) override
\reimp
LocalSocketError
The LocalServerError enumeration represents the errors that can occur.
@ UnsupportedSocketOperationError
void errorOccurred(QLocalSocket::LocalSocketError socketError)
\inmodule QtCore
Definition qobject.h:103
QObject * parent() const
Returns a pointer to the parent object.
Definition qobject.h:346
\inmodule QtCore
Definition qsettings.h:30
QVariant value(QAnyStringView key, const QVariant &defaultValue) const
Returns the value for setting key.
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
void clear()
Clears the contents of the string and makes it null.
Definition qstring.h:1252
QString arg(qlonglong a, int fieldwidth=0, int base=10, QChar fillChar=u' ') const
Definition qstring.cpp:8870
The QTcpSocket class provides a TCP socket.
Definition qtcpsocket.h:18
uint toUInt(bool *ok=nullptr) const
Returns the variant as an unsigned int if the variant has userType() \l QMetaType::UInt,...
else opt state
[0]
void newState(QList< State > &states, const char *token, const char *lexem, bool pre)
Combined button and popup list for selecting options.
DBusConnection const char DBusError * error
EGLOutputPortEXT port
#define qWarning
Definition qlogging.h:166
#define SLOT(a)
Definition qobjectdefs.h:52
#define SIGNAL(a)
Definition qobjectdefs.h:53
GLenum GLsizei GLuint GLint * bytesWritten
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
const GLubyte * c
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
#define tr(X)
#define emit
unsigned short quint16
Definition qtypes.h:48
long long qint64
Definition qtypes.h:60
ptrdiff_t qintptr
Definition qtypes.h:166
QSettings settings("MySoft", "Star Runner")
[0]
QTcpSocket * socket
[1]
QLayoutItem * child
[0]