Ошибка при использовании QTcpSocket

Я создаю (очень простой) MJPG сервер для отображения данных веб-камеры в браузере. Мне частично удалось сделать это до сих пор.

Вот мой код:

TcpServer::TcpServer(QObject *parent) :
QObject(parent)
{
server = new QTcpServer(this);
// whenever a user connects, it will emit signal
connect(server, SIGNAL(newConnection()),
this, SLOT(newConnection()));
if (!server->listen(QHostAddress::Any, 9999))
qDebug() << "Server could not start";
else
qDebug() << "Server started!";
}
...
void TcpServer::newConnection()
{
QTcpSocket *socket = server->nextPendingConnection();
QByteArray ContentType = ("HTTP/1.0 200 OK\r\n" \
"Cache-Control: no-cache\r\n" \
"Cache-Control: private\r\n" \
"Content-Type: multipart/x-mixed-replace;boundary=--boundary\r\n");
socket->write(ContentType);
std::vector<uchar> buff;
Mat img; //OpenCV Material
while (1) {
// Image to Byte Array via OPENCV Method
buff.clear();buff.empty();
vCapture->read(img); //Read from webcam

imencode(".jpg", img, buff, compression_params);
std::string content(buff.begin(), buff.end());
QByteArray CurrentImg(QByteArray::fromStdString(content));
QByteArray BoundaryString = ("--boundary\r\n" \
"Content-Type: image/jpeg\r\n" \
"Content-Length: ");
BoundaryString.append(QString::number(CurrentImg.length()));
BoundaryString.append("\r\n\r\n");

socket->write(BoundaryString);
socket->write(CurrentImg); // Write The Encoded Image
socket->flush();
}

}

Эта проблема —

Когда я запускаю эту программу, отображается первое изображение. После этого в приложении постоянно печатается следующая ошибка:

QIODevice::write (QTcpSocket): device not open

Выглядело так, как будто сокет закрылся, поэтому я использовал реинициализацию сокета, вот так: socket = server->nextPendingConnection();, хотя приложение выдало ошибку с этим кодом. Любая помощь о том, как это исправить?

РЕДАКТИРОВАТЬ —

Я попробовал лямбда-метод, и он работал нормально. Тем не мение, Я до сих пор сталкиваюсь с 2 проблемами

  1. Размер изображения должен быть слишком низким (около 270х480 с самым низким качеством JPG)

  2. (БОЛЕЕ ВАЖНЫЙ) Я должен вручную нажать кнопку перезагрузки в браузере, чтобы перезагрузить изображение, оно не переключается автоматически с одного изображения на другое.

1

Решение

Вот код, который я использовал, чтобы открыть потоковый сервер MJPEG в мой оригинальный проект. Возможно, это поможет вам выяснить вашу проблему.

void MjpegStreamingEngine::StartServer(){

m_TcpHttpServer = new QTcpServer();

m_TcpHttpServer->connect(m_TcpHttpServer,
SIGNAL(newConnection()),
this,
SLOT(TcpHttpconnected()));

m_TcpHttpServer->listen(QHostAddress::Any,
8889);
}

void MjpegStreamingEngine::TcpHttpconnected(){

m_TcpHttpClient = m_TcpHttpServer->nextPendingConnection();

m_TcpHttpClient->connect(m_TcpHttpClient,
SIGNAL(readyRead()),
this,
SLOT(TcpHttpreadyRead()));

}

void MjpegStreamingEngine::TcpHttpreadyRead(){

m_TcpHttpClient->readAll(); // Discard "Get Request String"
QByteArray ContentType = ("HTTP/1.0 200 OK\r\n" \
"Server: en.code-bude.net example server\r\n" \
"Cache-Control: no-cache\r\n" \
"Cache-Control: private\r\n" \
"Content-Type: multipart/x-mixed-replace;boundary=--boundary\r\n\r\n");

m_TcpHttpClient->write(ContentType);while(1){

if (m_TcpHttpClient->isOpen())
{

// Send Image

QThread::msleep(10);

}else{
return;
}

}

m_TcpHttpClient->disconnect(); //Should never be Reached
}
1

Другие решения

Похоже, розетка была закрыта

Вместо того, чтобы угадывать, подключитесь к сигналам ошибки TCPServer а также TCPSocket знать, когда происходят ошибки или когда клиент отключается.

Проблема у вас есть в то время как (1) петля. Qt является событийного Framework, поэтому наличие кода в бесконечном цикле в главном потоке будет препятствовать доставке событий.

Вместо бесконечного цикла подключитесь к QTcpSocket :: readyRead сигнализировать и обрабатывать данные при вызове подключенного слота.

Qt демонстрирует это с помощью Сервер удачи а также Клиент удачи пример кода.

Если вы используете C ++ 11, Вы можете использовать соединение с лямбда-функцией для обработки readyRead, как это

void TcpServer::newConnection()
{
...

QTcpSocket *m_TcpHttpClient = server->nextPendingConnection();
connect(m_TcpHttpClient, &QTcpSocket::readyRead, [=](){

// handle received data here

});

}
2

По вопросам рекламы [email protected]