109bool QSctpSocketPrivate::canReadNotification()
112#if defined (QSCTPSOCKET_DEBUG)
113 qDebug(
"QSctpSocketPrivate::canReadNotification()");
117 if (!q->isInDatagramMode())
118 return QTcpSocketPrivate::canReadNotification();
120 const int savedCurrentChannel = currentReadChannel;
121 bool currentChannelRead =
false;
123 qsizetype datagramSize = incomingDatagram.size();
124 QIpPacketHeader header;
128 qint64 bytesToRead = socketEngine->bytesAvailable();
129 if (bytesToRead == 0) {
136 Q_ASSERT((datagramSize + qsizetype(bytesToRead)) < QByteArray::maxSize());
137 incomingDatagram.resize(datagramSize +
int(bytesToRead));
139#if defined (QSCTPSOCKET_DEBUG)
140 qDebug(
"QSctpSocketPrivate::canReadNotification() about to read %lli bytes",
143 qint64 readBytes = socketEngine->readDatagram(
144 incomingDatagram.data() + datagramSize, bytesToRead, &header,
145 QAbstractSocketEngine::WantAll);
146 if (readBytes <= 0) {
147 if (readBytes == -2) {
148 incomingDatagram.resize(datagramSize);
149 return currentChannelRead;
152 socketEngine->close();
153 if (readBytes == 0) {
154 setErrorAndEmit(QAbstractSocket::RemoteHostClosedError,
155 QSctpSocket::tr(
"The remote host closed the connection"));
157#if defined (QSCTPSOCKET_DEBUG)
158 qDebug(
"QSctpSocketPrivate::canReadNotification() read failed: %s",
159 socketEngine->errorString().toLatin1().constData());
161 setErrorAndEmit(socketEngine->error(), socketEngine->errorString());
164#if defined (QSCTPSOCKET_DEBUG)
165 qDebug(
"QSctpSocketPrivate::canReadNotification() disconnecting socket");
167 q->disconnectFromHost();
168 return currentChannelRead;
170 datagramSize +=
int(readBytes);
171 }
while (!header.endOfRecord);
173#if defined (QSCTPSOCKET_DEBUG)
174 qDebug(
"QSctpSocketPrivate::canReadNotification() got datagram from channel %i, size = %i",
175 header.streamNumber, datagramSize);
179 if (!q->isReadable()) {
180 incomingDatagram.clear();
185 Q_ASSERT(header.streamNumber < readBuffers.size());
186 incomingDatagram.resize(datagramSize);
187 readBuffers[header.streamNumber].setChunkSize(0);
188 readBuffers[header.streamNumber].append(incomingDatagram);
189 incomingDatagram = QByteArray();
191 if (readHeaders.size() != readBuffers.size())
192 readHeaders.resize(readBuffers.size());
193 readHeaders[header.streamNumber].push_back(header);
196 if (header.streamNumber == savedCurrentChannel)
197 currentChannelRead =
true;
198 emitReadyRead(header.streamNumber);
200 }
while (state == QAbstractSocket::ConnectedState);
202 return currentChannelRead;
207bool QSctpSocketPrivate::writeToSocket()
210#if defined (QSCTPSOCKET_DEBUG)
211 qDebug(
"QSctpSocketPrivate::writeToSocket()");
215 if (!q->isInDatagramMode())
216 return QTcpSocketPrivate::writeToSocket();
221 QIpPacketHeader defaultHeader;
222 const int savedCurrentChannel = currentWriteChannel;
223 bool currentChannelWritten =
false;
226 transmitting =
false;
228 for (
int channel = 0; channel < writeBuffers.size(); ++channel) {
229 QRingBuffer &channelBuffer = writeBuffers[channel];
231 if (channelBuffer.isEmpty())
234 const bool hasHeader = (channel < writeHeaders.size())
235 && !writeHeaders[channel].empty();
236 QIpPacketHeader &header = hasHeader ? writeHeaders[channel].front() : defaultHeader;
237 header.streamNumber = channel;
238 qint64 sent = socketEngine->writeDatagram(channelBuffer.readPointer(),
239 channelBuffer.nextDataBlockSize(),
243 return currentChannelWritten;
245 socketEngine->close();
246#if defined (QSCTPSOCKET_DEBUG)
247 qDebug(
"QSctpSocketPrivate::writeToSocket() write error, aborting. %s",
248 socketEngine->errorString().toLatin1().constData());
250 setErrorAndEmit(socketEngine->error(), socketEngine->errorString());
252 q->disconnectFromHost();
253 return currentChannelWritten;
255 Q_ASSERT(sent == channelBuffer.nextDataBlockSize());
256#if defined (QSCTPSOCKET_DEBUG)
257 qDebug(
"QSctpSocketPrivate::writeToSocket() sent datagram of size %lli to channel %i",
263 channelBuffer.read();
265 writeHeaders[channel].pop_front();
268 if (channel == savedCurrentChannel)
269 currentChannelWritten =
true;
270 emitBytesWritten(sent, channel);
273 if (state == QAbstractSocket::UnconnectedState) {
274#if defined (QSCTPSOCKET_DEBUG)
275 qDebug(
"QSctpSocketPrivate::writeToSocket() socket is closing - returning");
277 return currentChannelWritten;
280 }
while (transmitting);
284 if (state == QAbstractSocket::ClosingState)
285 q->disconnectFromHost();
287 socketEngine->setWriteNotificationEnabled(
false);
289 return currentChannelWritten;
332qint64 QSctpSocket::readData(
char *data, qint64 maxSize)
337 if (d->currentReadChannel < d->readHeaders.size())
338 d->readHeaders[d->currentReadChannel].clear();
340 return QTcpSocket::readData(data, maxSize);
345qint64 QSctpSocket::readLineData(
char *data, qint64 maxlen)
350 if (d->currentReadChannel < d->readHeaders.size())
351 d->readHeaders[d->currentReadChannel].clear();
353 return QTcpSocket::readLineData(data, maxlen);
440QNetworkDatagram QSctpSocket::readDatagram()
444 if (!isReadable() || !isInDatagramMode()) {
445 qWarning(
"QSctpSocket::readDatagram(): operation is not permitted");
446 return QNetworkDatagram();
449 if (d->currentReadChannel >= d->readHeaders.size()
450 || d->readHeaders[d->currentReadChannel].size() == 0) {
451 Q_ASSERT(d->buffer.isEmpty());
452 return QNetworkDatagram();
455 QNetworkDatagram result(*
new QNetworkDatagramPrivate(d->buffer.read(),
456 d->readHeaders[d->currentReadChannel].front()));
457 d->readHeaders[d->currentReadChannel].pop_front();
459#if defined (QSCTPSOCKET_DEBUG)
460 qDebug(
"QSctpSocket::readDatagram() returning datagram (%p, %i, \"%s\", %i)",
461 result.d->data.constData(),
462 result.d->data.size(),
463 result.senderAddress().toString().toLatin1().constData(),
464 result.senderPort());
476bool QSctpSocket::writeDatagram(
const QNetworkDatagram &datagram)
480 if (!isWritable() || d->state != QAbstractSocket::ConnectedState || !d->socketEngine
481 || !d->socketEngine->isValid() || !isInDatagramMode()) {
482 qWarning(
"QSctpSocket::writeDatagram(): operation is not permitted");
486 if (datagram.d->data.isEmpty()) {
487 qWarning(
"QSctpSocket::writeDatagram() is called with empty datagram");
492#if defined QSCTPSOCKET_DEBUG
493 qDebug(
"QSctpSocket::writeDatagram(%p, %i, \"%s\", %i)",
494 datagram.d->data.constData(),
495 datagram.d->data.size(),
496 datagram.destinationAddress().toString().toLatin1().constData(),
497 datagram.destinationPort());
500 if (d->writeHeaders.size() != d->writeBuffers.size())
501 d->writeHeaders.resize(d->writeBuffers.size());
502 Q_ASSERT(d->currentWriteChannel < d->writeHeaders.size());
503 d->writeHeaders[d->currentWriteChannel].push_back(datagram.d->header);
504 d->writeBuffer.setChunkSize(0);
505 d->writeBuffer.append(datagram.d->data);
507 d->socketEngine->setWriteNotificationEnabled(
true);