Qt: tcp-клиент Python отправляет данные через сокет.Как читать эти байты с помощью Qt? - PullRequest
1 голос
/ 25 января 2010

Положение: У меня есть tcp клиент с Python и tcp сервер с Qt. Я пытаюсь отправить байты с моим клиентом, но не могу заставить сервер Qt прочитать эти байты.

Используя Python, сделанный клиентом и сервером, все работает отлично. Также я могу без проблем заставить мой клиент Python работать с C # сервером.

Код для клиента Python:

import socket
import sys

HOST = 'localhost'
PORT = 50505

try:
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error as msg:
    sys.stderr.write("[ERROR] %s\n" % msg)
    sys.exit(1)

try:
    sock.connect((HOST, PORT))
except socket.error as msg: 
    sys.stderr.write("[ERROR] %s\n" % msg)
    sys.exit(2)

sock.send(b'Hello World!\r\n')

Я пробовал примеры кода e.q fortuneserver / fortuneclient, но они не работали. Bytesavailable () всегда равно 0.

Итак, вопрос в том, как я могу прочитать в своем приложении Qt "Hello World!" линия ? Мне просто нужна эта функция, которая запускается, когда сервер испускает сигнал newConnection ().

connect(tcpServer, SIGNAL(newConnection()), this, SLOT(startRead()));

UPDATE:

Часть кода для сервера Qt:

void Server::startRead()
{
QDataStream in(tcpSocket);
in.setVersion(QDataStream::Qt_4_0);
QString ipAddress;

if (blockSize == 0) {
    if (tcpSocket->bytesAvailable() < (int)sizeof(quint16))
        return;
    in >> blockSize;
}

if (tcpSocket->bytesAvailable() < blockSize)
    return;

QString nextFortune;
in >> nextFortune;

statusLabel->setText(nextFortune);

    ABOVE IS FROM FORTUNE CLIENT EXAMPLE. 

    BELOW IS FROM ANOTHER EXAMPLE.
/*
char buffer[128] = {0};
QTcpSocket *client = tcpServer->nextPendingConnection();
qDebug() << client->bytesAvailable();
for (int i=0; i<100; i++)
{
    client->read(buffer, client->bytesAvailable());
    qDebug() << buffer;
    std::string sString(buffer);
    QString qString(sString.c_str());
    statusLabel->setText(qString);
}
    */
}

Эта последняя часть довольно плохая. Я пытался что-то сделать, но понятия не имею, что я делаю с Qt:)

Ответы [ 2 ]

1 голос
/ 27 января 2010

Вам нужно организовать чтение кода при наличии доступных данных. Из вашего описания пока нет доступных данных при запуске startRead ().

Я полагаю, вы позвонили QTcpServer::nextPendingConnection, чтобы получить tcpSocket в startRead()? Если нет, то вам нужно это сделать.

Просто подключите сигнал readyRead от вашего tcpSocket или client к слоту doRead(), проверьте bytesAvailable() и прочитайте в этом слоте.

Этот слот будет вызываться при поступлении новых данных.

Вас также может заинтересовать сигнал disconnected() от вашего сокета TCP, чтобы узнать, когда он завершит отправку данных.

0 голосов
/ 25 января 2010

Код сервера, который вы прикрепили, работает следующим образом: каждый «пакет» (логический) состоит из поля size и данных, следующих за size.

В основном это выглядит так:

  1. Прочитайте quint16, если нет достаточно байтов для чтения, дождитесь больше.
  2. quint16 прочитайте, подождите, пока мы не получим по крайней мере, сумма quint16 быть прочитанным.
  3. Как только у нас будет достаточно, мы можем прочитать в данные.

После того, как мы поняли, что даже если вы напишите длину пакета, как того ожидает сервер, то, что вы пытаетесь сделать, все равно не будет работать. Это потому, что сервер читает QString из сокета. Клиент пишет необработанную строку Python, я предполагаю, что он просто записывает старый ASCII в сокет. Сервер использует QDataStream для чтения из сокета (это стандартный способ сериализации в Qt). Если вы посмотрите на реализацию оператора QString << <a href="http://qt.gitorious.org/qt/qt/blobs/master/src/corelib/tools/qstring.cpp#line7271" rel="nofollow noreferrer"> здесь , это гораздо больше, чем просто чтение строки ASCII.

Если вы не можете изменить свой сервер, смените клиента. Вы можете увидеть реализацию клиента удачи в примерах, которые поставляются с PyQt.

...