[Solved] QTcpServer and Telnet full duplex problem.
Hello, thanks for time dedicated to my problem.
I am having a problem developing a threaded server thats gets commands from a telnet console and writes data on it.
Normal operation im looking forward is:
1- Server listens for new connections (telnet client).
2- As new connection appears, a thread is generated.
3- Telnet client sends commands to server to configure message treating.
4- Server can respond with data to telnet client that is shown in console.
5- Items 3 and 4 can be repeated over operation.
As i run server, it listens on a port, telnet connects properly, and i can read and process data from console.
As soon as server writes on console, no more commands from telnet console are read on server side (seems like server blocks reading).
I am posting some "trimmed" code with more important parts containing communication.
This class waits for new connections and creates threads to work with them
class ServerToTelnet : public QTcpServer
explicit ServerToTelnet(QObject *parent = 0);
void fireSignal(QByteArray msg); QByteArray bytesOut;
void incomingConnection(int socketDescriptor);
ServerToTelnet ::ServerToTelnet (QObject *parent) :
void ServerToTelnet ::incomingConnection(int socketDescriptor)
TelnetThread *thread = new TelnetThread(socketDescriptor, this);
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); connect(this, SIGNAL(msgToTreatSignal(QByteArray)), thread, SLOT(msgToTreatSlot(QByteArray))); thread->start();
void ServerToTelnet ::fireSignal(QByteArray msg)
This class generates thread code.
class TelnetThread : public QThread
explicit TelnetThread(int ID, QObject *parent = 0);
msgType msgToTreat; void run(); void treatMessage(); QString passed(); friend QDataStream &operator>>(QDataStream &bytesIn, msgType &msg);
void msgToTreatSlot(QByteArray); void ListSlot(); void informErrorSlot();
TelnetThread::TelnetThread(int ID, QObject *parent) :
socketDescriptor = ID;
client = new QTcpSocket();
client->setSocketDescriptor(socketDescriptor); connect(client, SIGNAL(readyRead()), this, SLOT(readCommand()), Qt::DirectConnection); connect(client, SIGNAL(disconnected()), this, SLOT(disconnected())); exec();
command = client->readLine(); conditions.setFileName("conditions.ini"); conditions.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text); conditions.write(command.toAscii()); conditions.close();
/* Work data */
QString result = passed(); client->write(result.toAscii()); client->flush();
void TelnetThread::msgToTreatSlot(QByteArray bytesIn)
streamIn >> msgToTreat; treatMessage();
/* QString generation */
I appreciate your help, i couldn´t find any related topics on Qt documentation/forums.
Thank you very much.
Try to make your own Client in Qt as you made Server.
Qt Docs give you such examples which are developed in Qt Whether it is your server or Client.
But a requeriment is to connect through telnet.
That´s why i am asking this, i already tested it with a client of my own and it works properly.
I think there must be a restriction on working with telnet i am not taking in consideration.
I think telent has its own behaviour so you cannot identify the state of telnet client.
Telnet is based on Protocol TCP/IP, and is supposed to be full-duplex.
I am not so familiar with Telnet, that's why im overlooking some "control" needed to make it work full-duplex.
Telnet sends data to my server correctly until server sends data to Telnet. That's the moment when communication turns Half-duplex (from server to telnet).
Telnet console says "Sent string ....." after send command, but i think it may be enqueueing data because in serverside no ready read signal is emmited.
I think i'm approaching a solution to Telnet Full-duplex problem.
Although many documentation says that all Telnet consoles work in a Full-duplex mode, I read RFC854 and find out its not true. Default work mode is Half-duplex.
Telnet works with GA (Go Ahead) command when one side of the socket finishes writing data.
There is a command that sets full-duplex mode, the SUPPRESS-GO-AHEAD.
As soon as thread is created (responding to a newConnection on Server) commands "IAC + WILL + SUPPRESS-GO-AHEAD" are sent setting a full-duplex terminal without any command at the end of socket writing.
Sending 0xFF, 0xFB, 0x03 to telnet terminal, full-duplex socket connection is guaranteed without need of any other command.
Hope it helps.