Wątek serwera wewnątrz klasy qt (potrzebujesz muteksu?)
Zrobiłem tę klasę serwera, która uruchamia wątek po wejściu w nowe połączenie. W niektórych przypadkach działa poprawnie, ale nie jest zbyt stabilna. Próbuję rozwiązać to, co zepsuje. Mój debugger mówi mi coś o qmutex. Jeśli ktoś może wykryć problem. ty
Łączy się z rodzicem za pomocą sygnału i gniazd oraz pobiera dane z powrotem.
Oto nagłówek:
#ifndef FORTUNESERVER_H
#define FORTUNESERVER_H
#include <QStringList>
#include <QTcpServer>
#include <QThread>
#include <QTcpSocket>
#include <string>
using namespace std;
class FortuneServer : public QTcpServer
{
Q_OBJECT
public:
FortuneServer(QObject *parent = 0);
public slots:
void procesServerString(string serverString);
void getStringToThread(string serverString);
protected:
void incomingConnection(int socketDescriptor);
private:
QStringList fortunes;
signals:
void procesServerStringToParent(string serverString);
void getStringToThreadSignal(string serverString);
};
class FortuneThread : public QObject
{
Q_OBJECT
public:
FortuneThread(int socketDescriptor, QObject *parent);
public slots:
void getString();
void sendString(string sendoutString);
signals:
void error(QTcpSocket::SocketError socketError);
void fromThreadString(string serverString);
void finished();
private:
int socketDescriptor;
QString text;
QTcpSocket tcpSocket;
};
#endif
i cc:
#include <stdlib.h>
#include <QtNetwork>
#include "MeshServer.hh"
#include <iostream>
#include "TableView.hh"
using namespace std;
FortuneServer::FortuneServer(QObject *parent)
: QTcpServer(parent)
{
}
void FortuneServer::procesServerString(string serverString){
emit procesServerStringToParent(serverString);
}
void FortuneServer::getStringToThread(string serverString){
emit getStringToThreadSignal(serverString);
}
void FortuneServer::incomingConnection(int socketDescriptor)
{
FortuneThread *serverthread = new FortuneThread(socketDescriptor, this);
//connect(&serverthread, SIGNAL(finished()), &serverthread, SLOT(deleteLater()));
QThread* thread = new QThread;
serverthread->moveToThread(thread);
connect(thread, SIGNAL(started()), serverthread, SLOT(getString()));
connect(serverthread, SIGNAL(fromThreadString(string)), this, SLOT(procesServerString(string)));
connect(this, SIGNAL(getStringToThreadSignal(string)), serverthread, SLOT(sendString(string)));
connect(serverthread, SIGNAL(finished()), thread, SLOT(quit()));
connect(serverthread, SIGNAL(finished()), serverthread, SLOT(deleteLater()));
connect(serverthread, SIGNAL(finished()), thread, SLOT(deleteLater()));
thread->start();
}
FortuneThread::FortuneThread(int socketDescriptor, QObject *parent)
: QObject(parent), socketDescriptor(socketDescriptor)
{
}
void FortuneThread::getString()
{
if (!tcpSocket.setSocketDescriptor(socketDescriptor)) {
emit error(tcpSocket.error());
cout<<"socket error"<<endl;
return;
}
//in part
if(!tcpSocket.waitForReadyRead(10000)){
emit finished();
return;
}
int joj = tcpSocket.bytesAvailable();
char inbuffer[1024];
tcpSocket.read(inbuffer,1024);
string instring;
instring = inbuffer;
instring.resize(joj);
emit fromThreadString(instring);
}
void FortuneThread::sendString(string sendoutString)
{
//out part
char buffer[1024];
int buffer_len = 1024;
int bytecount;
memset(buffer, '\0', buffer_len);
string outstring = sendoutString;
int TempNumOne= (int)outstring.size();
for (int a=0;a<TempNumOne;a++)
{
buffer[a]=outstring[a];
}
QByteArray block;
block = buffer;
tcpSocket.write(block);
tcpSocket.disconnectFromHost();
tcpSocket.waitForDisconnected();
emit finished();
}
to jest od rodzica:
//server start
QHostAddress adr;
adr.setAddress( QString("127.0.0.1") );
adr.toIPv4Address();
quint16 port = 1101;
if (!server.listen( adr, port)) {
QMessageBox::critical(this, tr("CR_bypasser"),
tr("Unable to start the server: %1.")
.arg(server.errorString()));
close();
return;
}
QString ipAddress;
ipAddress = server.serverAddress().toString();
statusLabel->setText(tr("The server is running on\n\nIP: %1\nport: %2\n\n"
"Run the Fortune Client example now.")
.arg(ipAddress).arg(server.serverPort()));
connect (&server, SIGNAL(procesServerStringToParent(string)), this, SLOT(procesServerString(string)));
connect (this, SIGNAL(StringToServer(string)), &server, SLOT(getStringToThread(string)));
edytuj: co próbuję zrobić:
Mam klienta (część silnika gry (Cryengine)), którego wysłałem, aby wysłać ciąg współrzędnych w grze i kilka innych rzeczy z gniazdem, tak jak to zrobiłem w łączu, który podałem wcześniej. To działa dobrze. Dostaję dane na porcie „127.0.0.1” 1101. Teraz potrzebuję tylko tych danych do oceny w moim własnym programie, który ma klasę TableView, wewnątrz której mogę zbierać współrzędne, które otrzymuję z ciągu, obliczam niektóre dane ze współrzędnych i następnie zwróć ten nowy ciąg z powrotem przez serwer do gameengine. W grze kliknę na obiekty, uzyskaj ich rdzeń, wyciągnij z tego ciąg (zawierający coor, entityid, itd ..), wyślij ten ciąg na serwer, który zwraca wyliczone informacje z TableView. Potrzebuję tylko tego jednokierunkowego przepływu tylko jednego klienta, który wysyła ciągi. Nie jestem pewien co do recv (hsock, buffer, buffer_len, 0), przypuszczam, że węzeł odpowiedzialny za wysyłanie ciągów w grze będzie czekał na ciąg powrotu? To jeden z moich pierwszych programów, w których jestem zdezorientowany ...