Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

QAbstractSocket Win - > Linux

316
15 апреля 2012 года
Alm3n
889 / / 29.05.2009
Хеллоу.
Сервер пишется под Ubuntu. В общих чертах:
Код:
ssa.sin_family = AF_INET;
ssa.sin_port = htons(DEFAULTCONNECTIONPORT);
ssa.sin_addr.s_addr = htonl(INADDR_ANY);//inet_addr("192.168.0.2");

    if(bind(s, sp, sz) == -1){
        exit(1);
    }
    if(listen(s, 50) == -1){
        exit(1);
    }
    while(1){
        if((c = accept(s, cp, &sz)) == -1) {
            exit(1);
        }

        memset((void*)&que,0,sizeof(struct query));
        recv(c,(void*)&que,sizeof(struct query),0);
        repl.replayPort = 13;
        repl.replyAnswer = SERVERGOOD;
        send(c, (void*)&repl, sizeof(struct reply), 0);
        close(c);
    }
Клиент пишутся под Win на Qt.
 
Код:
soc = new QAbstractSocket(QAbstractSocket::TcpSocket, NULL);
    connect(soc,SIGNAL(connected()),this,SLOT(slotSocketConnectedSuccessful()));
    connect(soc,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(slotSocketConnectedFailed(QAbstractSocket::SocketError)));
    connect(soc,SIGNAL(hostFound()),this,SLOT(slotSocketHostFound()));
    std::cout << "Connection...\n";
    soc->connectToHost(QString::fromStdString(addr),port);
Почему-то под виндой сокет не переходит в состояние Connected. Хост находит, да дальше подвисает. Если не дожидаться состояния Connected передавать по каналу данные, то сервером они принимаются корректно, сервер отправляет ответные данные и на клиент приходит пустота.
Запуск в Virtual Box local networking. В ubuntu поднимал интерфейс ifconfig etho 192.168.0.2 netmask 255.255.255.0.
Два вопроса:
1) Почему клиент не переходит в стадию Connected?
2) Почему клиент получает от сервера обнулённые данные?
316
15 апреля 2012 года
Alm3n
889 / / 29.05.2009
Дописал
 
Код:
soc->waitForConnected();
У клиента после
 
Код:
soc->connectToHost(QString::fromStdString(addr),port);
И всё заработало. О_о
UPD: Не, ни фига. Оно то работает, то не работает.
UPD1:
Убрал создание сокета из потока. Там какой-то трабл был с таймером, принадлежащему сокету. Подозреваю, что он не создавался или не убивался(иногда всплывало сообщение о том, что нельзя создать дочерний объект из иного треда или убить таймер по той же причине). Успешно получены данные в 80% запусках программы. В чём истинная причина неполадок так и не понял.
277
15 апреля 2012 года
arrjj
1.7K / / 26.01.2011
Версия Qt? В чем собираешь? Покажи больше кода.
316
15 апреля 2012 года
Alm3n
889 / / 29.05.2009
4.7.4 Qt Creator.

Код:
#include "socketthread.h"

void SocketThread::run()
{
    soc = new QAbstractSocket(QAbstractSocket::TcpSocket, 0);
    connect(soc,SIGNAL(connected()),this,SLOT(slotSocketConnectedSuccessful()));
    connect(soc,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(slotSocketConnectedFailed(QAbstractSocket::SocketError)));
    connect(soc,SIGNAL(hostFound()),this,SLOT(slotSocketHostFound()));
    std::cout << "Connection...\n";
    soc->connectToHost(QString::fromStdString(addr),port);
    soc->waitForConnected(500000);
}

void SocketThread::slotSocketConnectedFailed(QAbstractSocket::SocketError socketError)
{
    QString host = QString::fromStdString(addr);
    std::cout << "Some error occures while connecting to host " << host.toStdString() << ":";
    std::cout << soc->errorString().toLocal8Bit().data() << std::endl;
    QCoreApplication::exit();
    return;
}

void SocketThread::slotSocketConnectedSuccessful()
{
    std::cout << "Connected to " << addr << " is successful\n";
    std::cout << "Send request\n";
    struct query* req = new query();
    memset(req->queryUserName,0,MAXUSERNAMELEN);
    strcpy(req->queryUserName,uname.c_str());
    int result;
    result = soc->write(reinterpret_cast<char*>(req),sizeof(struct query));
    soc->waitForBytesWritten(500000);
    if (result == -1)
    {
        std::cout << "Some error occures while sending request\n";
        delete req;
        return;
    }
    std::cout << "Geting answer\n";
    struct reply* resp = new reply();
    result = soc->read(reinterpret_cast<char*>(resp),sizeof(struct reply));
    std::cout << "Waiting for ready read\n";
    soc->waitForReadyRead(500000);
    std::cout << "Successfuly readed or error\n";
    if (result == -1)
    {
        std::cout << "Some error occures while reading answer\n";
    }
    else if (resp->replyAnswer == SERVERERROR)
    {
        std::cout << "Some error occures on the server. VNC is not started or same\n";
    }
    else if (resp->replyAnswer == SERVERGOOD)
    {
        std::cout << "Port of VNC server is "<< resp->replayPort << std::endl;
    }
    else
    {
        std::cout << "Unknown server answer\n";
    }
    delete resp;
    delete req;
    QCoreApplication::exit();
    return;
}

void SocketThread::slotSocketHostFound()
{
    std::cout << "Host successfuly found\n";
    flag = true;
}

void SocketThread::slotStateChanged(QAbstractSocket::SocketState state)
{
    std::cout << state << "\n";
}
277
16 апреля 2012 года
arrjj
1.7K / / 26.01.2011
>< WHY????? ПОЧЕМУ???? ПОЧЕМУ ТЫ НЕ ЧИТАЕШЬ ДОКУМЕНТАЦИЮ??? ПЕРВЫЙ ЖЕ ПРИМЕР В QThread:
Код:
class MyThread : public QThread
 {
 public:
     void run();
 };

 void MyThread::run()
 {
     QTcpSocket socket;
     // connect QTcpSocket's signals somewhere meaningful
     ...
     socket.connectToHost(hostName, portNumber);
     exec();
 }
exec(); <-запускает внутрипоточный loop событий, если run (как у тебя) не содержит бесконечного цикла while(1)
277
16 апреля 2012 года
arrjj
1.7K / / 26.01.2011
И exit(); потом для завершения потока
316
16 апреля 2012 года
Alm3n
889 / / 29.05.2009
А я не писал, что в конечно реализации избавился от потока и оно всё равно не работало? Что-то не помню, чтобы нужно было exec вызывать, разве при вызове start внутренний цикл сам не запускается? По-моему, так было всегда, хотя если и не так, то это не особо теперь важно. Вот заголовок:
Код:
#include <QThread>
#include <QtNetwork/QAbstractSocket>
#include "constants.h"
#include <iostream>
#include <QtCore/QCoreApplication>
#include <QObject>

class SocketThread : QObject
{
    Q_OBJECT

    std::string uname;
    std::string addr;
    int port;
    QAbstractSocket* soc;
public:

    SocketThread(std::string& UName, std::string& Addr, int Port = 32500):uname(UName),addr(Addr),port(Port)
    {
    }
    ~SocketThread()
    {
        delete soc;
    }

    void run();

private slots:
    void slotSocketConnectedSuccessful();
    void slotSocketConnectedFailed(QAbstractSocket::SocketError socketError);
    void slotSocketHostFound();
    void slotStateChanged(QAbstractSocket::SocketState state);
};
277
16 апреля 2012 года
arrjj
1.7K / / 26.01.2011
 
Код:
struct reply* resp = new reply();
     if(!soc->waitForReadyRead(500000))//Сначала ждем потом читаем а не наоборот
{
std::cout<<"no reply.."<<std::endl;
return;
}
//Все что ниже я бы вынес в слот, приконнекченый к readyRead сигналу
    result = soc->read(reinterpret_cast<char*>(resp),sizeof(struct reply));
    std::cout << "Waiting for ready read\n";


А fortune (из примеров) клиент/сервер у тебя норм собираются и работают?
277
16 апреля 2012 года
arrjj
1.7K / / 26.01.2011
И ещеб я переделал (хз как у тебя оформлен reply) добавил бы ему методы для адекватной передачи по сети, а то кастинг меня както смущает.
316
16 апреля 2012 года
Alm3n
889 / / 29.05.2009
Reply метод никак не добавить, эта структура потом используется в демоне на Си, там всего два поля типа инта. Сервер и клиент собираются нормально, там какая-то цитата должна приходить, да?
277
16 апреля 2012 года
arrjj
1.7K / / 26.01.2011
И еще
 
Код:
--- if (result == -1)
+++ if (result == -1 || result <> sizeof(struct blahblah))
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог