crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> QTcpServer не слушает порт, хотя говорит что слушает
niklep
  опции профиля:
сообщение 23.4.2011, 20:32
Сообщение #1


Новичок


Группа: Новичок
Сообщений: 6
Регистрация: 11.4.2011
Пользователь №: 2590

Спасибо сказали: 0 раз(а)




Репутация:   0  


Доброго времени суток. Пишу службу под windows, которая должна, помимо других действий, создавать серверный сокет и слушать его на предмет соединений. С этим казалось бы проблем быть не должно. Однако, несмотря на то, что объект класса QTcpServer говорит мне, что он слушает порт, этого не происходит. Т.е. меня обманывают=)
Вот кусок кода:
tcpServer = new QTcpServer(this);
        if (!tcpServer->listen(QHostAddress::LocalHost, nPort))
        {
                qDebug() << "Unable to start Server: " << tcpServer->errorString();
                tcpServer->close();
                return;
        }
        connect(tcpServer, SIGNAL(newConnection()),
                this, SLOT(slotNewConnection()));
        qDebug() << tcpServer->isListening() << "TCPSocket listen on port" << nPort;

Так вот. Ошибки не происходит, сокет создается. Последняя строка с qDebug() говорит следующее:
true TCPSocket listen on port 6667

Тем временем netstat не видит открытого порта, nmap также, telnet также о_0
Что не так? Службе нужны какие-то привилегии для открытия порта? Так я ей уже указал под админом запускаться, без толку.
P.S. Данный код для создания сокета прекрасно работает в моем маленьком тестовом проекте, здесь не хочет.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
silver47
  опции профиля:
сообщение 24.4.2011, 5:57
Сообщение #2


Активный участник
***

Группа: Участник
Сообщений: 356
Регистрация: 1.4.2010
Пользователь №: 1584

Спасибо сказали: 40 раз(а)




Репутация:   6  


В проект network добавить не забыли?

Вообще на каждое входящее соединение QTcpServer создает отдельный QTcpSocket:
void TripServer::incomingConnection(int socketId)
{
    ClientSocket *socket = new ClientSocket(this);
    socket->setSocketDescriptor(socketId);
}


У Вас подобное имеется?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
niklep
  опции профиля:
сообщение 24.4.2011, 9:36
Сообщение #3


Новичок


Группа: Новичок
Сообщений: 6
Регистрация: 11.4.2011
Пользователь №: 2590

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(silver47 @ 24.4.2011, 7:57) *
В проект network добавить не забыли?

"Network library" через QT Project Settings добавлен.

Вот код моего класса:
#include <serversocket.h>

ServerSocket::ServerSocket(int nPort, ComHandler *com)
    : m_nNextBlockSize(0)
{
    temp_com = com;
    tcpServer = new QTcpServer(this);
    if (!tcpServer->listen(QHostAddress::LocalHost, nPort))
    {
        qDebug() << "Unable to start Server: " << tcpServer->errorString();
        tcpServer->close();
        return;
    }
    connect(tcpServer, SIGNAL(newConnection()),
        this, SLOT(slotNewConnection())); // слот вызывается при каждом присоединении нового клиента
    qDebug() << tcpServer->isListening() << "TCPSocket listen on port" << nPort;
}

void ServerSocket::slotNewConnection()
{
    QTcpSocket* clientSocket = tcpServer->nextPendingConnection();
    connect(clientSocket, SIGNAL(disconnected()),
        clientSocket, SLOT(deleteLater()));
    connect(clientSocket, SIGNAL(readyRead()),
        this, SLOT(slotReadClient()));
    sendToClient(clientSocket, "Server Response: Connected!");
}

void ServerSocket::slotReadClient()
{
    QTcpSocket* clientSocket = (QTcpSocket*)sender();
    QDataStream in(clientSocket);
    in.setVersion(QDataStream::Qt_4_5);
    for (;;)
    {
        if (!m_nNextBlockSize)
        {
            if (clientSocket->bytesAvailable() < sizeof(quint16))
                break;
            in >> m_nNextBlockSize;
        }
        if (clientSocket->bytesAvailable() < m_nNextBlockSize)
            break;
        QTime time;
        QString str;
        in >> time >> str;
        QByteArray ba = str.toLatin1(); // переводим QString
        const char *str2 = ba.data(); // в const char
        temp_com->writeToPort(str2);
        m_nNextBlockSize=0;
        sendToClient(clientSocket, "Server Response: Received \"" + str + "\"");
    }
    
}

void ServerSocket::sendToClient(QTcpSocket* pSocket, const QString& str)
{
    QByteArray arrBlock;
    QDataStream out(&arrBlock, QIODevice::WriteOnly);
    out.setVersion(QDataStream::Qt_4_5);
    out << quint16(0) << QTime::currentTime() << str;

    out.device()->seek(0);
    out << quint16(arrBlock.size() - sizeof(quint16));

    pSocket->write(arrBlock);
}

Вроде как все что надо создается...
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
niklep
  опции профиля:
сообщение 24.4.2011, 11:28
Сообщение #4


Новичок


Группа: Новичок
Сообщений: 6
Регистрация: 11.4.2011
Пользователь №: 2590

Спасибо сказали: 0 раз(а)




Репутация:   0  


Вот наткнулся на тему:
http://www.qtforum.org/article/27590/solve...l-not-work.html
В ней говорится, что служба (и ее конфиг в моем случае) должны лежать в windows\system32. Я так и сделал, но проблема не исчезла. Запускать пробовал как из командной строки ключом -e, так и из апплета "Службы".
Может еще есть какая-то хитрость с путями/правами?
И еще: емеет ли значение, что в main-файле службы имеется следующий код:
COMService service(argc, argv);
return service.exec();

А когда создаешь обычное приложение, то там
QApplication app(argc, argv);
return app.exec()

??? Ибо это единственное существенное различие в коде между службой и приложением (еще раз напомню, просто приложение у меня работает с этим классом ServerSocket)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
niklep
  опции профиля:
сообщение 24.4.2011, 18:12
Сообщение #5


Новичок


Группа: Новичок
Сообщений: 6
Регистрация: 11.4.2011
Пользователь №: 2590

Спасибо сказали: 0 раз(а)




Репутация:   0  


Проблему решил. Но не понял почему именно так=) Описываю:
Ранее метод start моей службы выглядел так (обратите внимание на последнюю строчку):
void COMService::start()
{
    QCoreApplication *app = application();
    qDebug() << "Start COMService";
    QString xmlFile = QApplication::applicationDirPath() + QDir::separator() + "config.xml";
    QFile file(xmlFile);
    QXmlInputSource source(&file); // помещаем документ в SAX-анализатор
    QXmlSimpleReader reader;
    XMLHandler handler;
    reader.setContentHandler(&handler);
    reader.parse(source); // метод parse запустит процесс анализа документа
    qDebug() << handler.portNumber << handler.comPort;
    ComHandler com(&handler);

    ServerSocket server(handler.portNumber, &com, app);
}

Теперь так:
void COMService::start()
{
    QCoreApplication *app = application();
    qDebug() << "Start COMService";
    QString xmlFile = QApplication::applicationDirPath() + QDir::separator() + "config.xml";
    QFile file(xmlFile);
    QXmlInputSource source(&file); // помещаем документ в SAX-анализатор
    QXmlSimpleReader reader;
    XMLHandler handler;
    reader.setContentHandler(&handler);
    reader.parse(source); // метод parse запустит процесс анализа документа
    qDebug() << handler.portNumber << handler.comPort;
    ComHandler com(&handler);

    server = new ServerSocket(handler.portNumber, &com, app);
}

В чем принципиальное отличие создания объекта первым методом и вторым? Гуру, подскажите. Я все время думал, что разницы никакой...
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
MoPDoBoPoT
  опции профиля:
сообщение 24.4.2011, 21:30
Сообщение #6


Участник
**

Группа: Участник
Сообщений: 172
Регистрация: 7.5.2009
Из: Москва
Пользователь №: 738

Спасибо сказали: 44 раз(а)




Репутация:   9  


Отличие в том, что в первом случае объект ServerSocket создаётся на стеке и, при выходе из метода start(), будет сразу же уничтожен, а во втором случае - в куче, из-за чего продолжает "жить" после выхода из метода start().
Эта особенность относится к C++, а не к Qt.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 27.12.2024, 22:30