Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qsctpserver.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 Alex Trotsenko <alex1973tr@gmail.com>
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5//#define QSCTPSERVER_DEBUG
6
7/*!
8 \class QSctpServer
9 \since 5.8
10
11 \brief The QSctpServer class provides an SCTP-based server.
12
13 \ingroup network
14 \inmodule QtNetwork
15
16 SCTP (Stream Control Transmission Protocol) is a transport layer
17 protocol serving in a similar role as the popular protocols TCP
18 and UDP. Like UDP, SCTP is message-oriented, but it ensures reliable,
19 in-sequence transport of messages with congestion control like
20 TCP. See the QSctpSocket documentation for more protocol details.
21
22 QSctpServer is a convenience subclass of QTcpServer that allows
23 you to accept incoming SCTP socket connections either in TCP
24 emulation or in datagram mode.
25
26 The most common way to use QSctpServer is to construct an object
27 and set the maximum number of channels that the server is
28 prepared to support, by calling setMaximumChannelCount(). You can set
29 the TCP emulation mode by passing a negative argument in this
30 call. Also, a special value of 0 (the default) indicates to use
31 the peer's value as the actual number of channels. The new incoming
32 connection inherits this number from the server socket descriptor
33 and adjusts it according to the remote endpoint settings.
34
35 In TCP emulation mode, accepted clients use a single continuous
36 byte stream for data transmission, and QSctpServer acts like a
37 plain QTcpServer. Call nextPendingConnection() to accept the
38 pending connection as a connected QTcpSocket. The function returns
39 a pointer to a QTcpSocket in QAbstractSocket::ConnectedState that
40 you can use for communicating with the client. This mode gives
41 access only to basic SCTP protocol features. The socket transmits SCTP
42 packets over IP at system level and interacts through the
43 QTcpSocket interface with the application.
44
45 In contrast, datagram mode is message-oriented and provides a
46 complete simultaneous transmission of multiple data streams
47 between endpoints. Call nextPendingDatagramConnection() to accept
48 the pending datagram-mode connection as a connected QSctpSocket.
49
50 \note This class is not supported on the Windows platform.
51
52 \sa QTcpServer, QSctpSocket, QAbstractSocket
53*/
54
55#include "qsctpserver.h"
56#include "qsctpserver_p.h"
57
58#include "qsctpsocket.h"
60
61#ifdef QSCTPSERVER_DEBUG
62#include <qdebug.h>
63#endif
64
65QT_BEGIN_NAMESPACE
66
67/*! \internal
68*/
69QSctpServerPrivate::QSctpServerPrivate()
70 : maximumChannelCount(0)
71{
72}
73
74/*! \internal
75*/
79
80/*! \internal
81*/
83{
84 QTcpServerPrivate::configureCreatedSocket();
85 if (socketEngine)
86 socketEngine->setOption(QAbstractSocketEngine::MaxStreamsSocketOption,
87 maximumChannelCount == -1 ? 1 : maximumChannelCount);
88}
89
90/*!
91 Constructs a QSctpServer object.
92
93 Sets the datagram operation mode. The \a parent argument is passed
94 to QObject's constructor.
95
96 \sa setMaximumChannelCount(), listen(), setSocketDescriptor()
97*/
98QSctpServer::QSctpServer(QObject *parent)
99 : QTcpServer(QAbstractSocket::SctpSocket, *new QSctpServerPrivate, parent)
100{
101#if defined(QSCTPSERVER_DEBUG)
102 qDebug("QSctpServer::QSctpServer()");
103#endif
104}
105
106/*!
107 Destroys the QSctpServer object. If the server is listening for
108 connections, the socket is automatically closed.
109
110 \sa close()
111*/
112QSctpServer::~QSctpServer()
113{
114#if defined(QSCTPSERVER_DEBUG)
115 qDebug("QSctpServer::~QSctpServer()");
116#endif
117}
118
119/*!
120 Sets the maximum number of channels that the server is prepared to
121 support in datagram mode, to \a count. If \a count is 0, endpoint
122 maximum number of channels value would be used. Negative \a count
123 sets a TCP emulation mode.
124
125 Call this method only when QSctpServer is in UnconnectedState.
126
127 \sa maximumChannelCount(), QSctpSocket
128*/
129void QSctpServer::setMaximumChannelCount(int count)
130{
131 Q_D(QSctpServer);
132 if (d->state != QAbstractSocket::UnconnectedState) {
133 qWarning("QSctpServer::setMaximumChannelCount() is only allowed in UnconnectedState");
134 return;
135 }
136#if defined(QSCTPSERVER_DEBUG)
137 qDebug("QSctpServer::setMaximumChannelCount(%i)", count);
138#endif
139 d->maximumChannelCount = count;
140}
141
142/*!
143 Returns the maximum number of channels that the accepted sockets are
144 able to support.
145
146 A value of 0 (the default) means that the number of connection
147 channels would be set by the remote endpoint.
148
149 Returns -1, if QSctpServer running in TCP emulation mode.
150
151 \sa setMaximumChannelCount()
152*/
153int QSctpServer::maximumChannelCount() const
154{
155 return d_func()->maximumChannelCount;
156}
157
158/*! \reimp
159*/
160void QSctpServer::incomingConnection(qintptr socketDescriptor)
161{
162#if defined (QSCTPSERVER_DEBUG)
163 qDebug("QSctpServer::incomingConnection(%i)", socketDescriptor);
164#endif
165
166 QSctpSocket *socket = new QSctpSocket(this);
167 socket->setMaximumChannelCount(d_func()->maximumChannelCount);
168 socket->setSocketDescriptor(socketDescriptor);
169 addPendingConnection(socket);
170}
171
172/*!
173 Returns the next pending datagram-mode connection as a connected
174 QSctpSocket object.
175
176 Datagram-mode connection provides a message-oriented, multi-stream
177 communication.
178
179 The socket is created as a child of the server, which means that
180 it is automatically deleted when the QSctpServer object is
181 destroyed. It is still a good idea to delete the object
182 explicitly when you are done with it, to avoid wasting memory.
183
184 This function returns null if there are no pending datagram-mode
185 connections.
186
187 \note The returned QSctpSocket object cannot be used from another
188 thread. If you want to use an incoming connection from another
189 thread, you need to override incomingConnection().
190
191 \sa hasPendingConnections(), nextPendingConnection(), QSctpSocket
192*/
193QSctpSocket *QSctpServer::nextPendingDatagramConnection()
194{
195 Q_D(QSctpServer);
196
197 for (auto it = d->pendingConnections.begin(), end = d->pendingConnections.end(); it != end; ++it) {
198 QSctpSocket *socket = qobject_cast<QSctpSocket *>(*it);
199 Q_ASSERT(socket);
200
201 if (socket->isInDatagramMode()) {
202 d->pendingConnections.erase(it);
203 Q_ASSERT(d->socketEngine);
204 d->socketEngine->setReadNotificationEnabled(true);
205 return socket;
206 }
207 }
208
209 return nullptr;
210}
211
212QT_END_NAMESPACE
213
214#include "moc_qsctpserver.cpp"
virtual ~QSctpServerPrivate()
void configureCreatedSocket() override