Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Сервер, чтение сокета
Форум на CrossPlatform.RU > Библиотеки > Qt > Qt Ввод/Вывод, Сеть. Межпроцессное взаимодействие
Zizilk
Имеется сервер.
Он должен получать данные от клиента написанного на PHP.
На сервере есть массив декрипторов подключённых сокетов.

Собственно вопрос...
Как организовать так, чтобы сервер пробегался по старым декрипторам из массива, получал данные, и в зависимости от них уже работал.
Я так понимаю делается это через бесконечный цикл, который управляется из паралельного потока?

Смотрел пример клиента но там больше подойдёт именно для клиентской части, где будет один сокет.


И ещё вопрос, как организовать чтение из сокета?
Если допустим с клиента на PHP передаются целые(пока) и дальше строковые значения?
Алексей1153
Обычно класс <какого-нибудь>сокета умеет себя извещать о пришедших данных (вернее, это делает система)
Zizilk
да я уже нашёл такую возможность у QT через чигнал "readytoread"

Но возник другой вопрос...

Есть PHP клиент и сервер на QT С++.

Связываются отлично.
Сервер отсылает клиенту пока тестовую строчку, клиент получает.
А вот с обратной связью не получается.
Клиент рапортует об удачной отправке.
На сервере запускается функция, говорящая о новых данных в сокете.
Но получает (null)

пока код такой

printf("Reciving\n");
QTcpSocket*  ClientSocket=(QTcpSocket*)sender();
QDataStream in(ClientSocket);
Char* str;
printf("Recived %s",str);


Перепечатывал с нетбука) он щас не подключён к инетупоэтому мог опечататься).


Там ещё проверка есть на целостность даных, но пока её закоментил)
Алексей1153
Ну, тут всё просто
Char* str;//неинициализированная переменная...
printf("Recived %s",str);//...используется
Zizilk
опечатался) пропустил строчку

printf("Reciving\n");
QTcpSocket*  ClientSocket=(QTcpSocket*)sender();
QDataStream in(ClientSocket);
Char* str;
in>>str;
printf("Recived %s",str);


Вот так вот выглядит код...
и всё равно 0
Алексей1153
Zizilk, а ты уверен, что оператор ">>" выделяет из кучи память под строку, присваивает адрес указателю и заполняет всю эту радость из in ?

Zizilk
Честно нет :blush2:
Я ещё не дошёл в книжке по С которую читаю до указателей, и плохо представляю ка они работают):blush2:
Те так должно выглядеть?)
printf("Reciving\n");
QTcpSocket*  ClientSocket=(QTcpSocket*)sender();
QDataStream in(ClientSocket);
Char str;
Char* str;
in>>str;
printf("Recived %s",str);
Алексей1153
Указатели - это переменные, которые хранят адрес оперативной памяти

Ты объявил указатель str , но не инициализировал ничем, там сейчас "мусор", то есть адрес невалидный. Вообще, возьми за правило инициализировать указатель нулём, если сразу нечем больше инициализировать

Char* str=0;

Когда указатель равен нулю, в дебаге легко поймать некорректное использование указателя.

Для класса QDataStream есть оператор
QDataStream & QDataStream::operator>> ( char *& s )
This is an overloaded function.
Reads the '\0'-terminated string s from the stream and returns a reference to the stream.
Space for the string is allocated using new -- the caller must destroy it with delete[].

Он принимает ссылку на указатель на char. То есть, судя по описанию, там действительно выделяется память из кучи, и ещё тебе надо потом удалить память обратно в кучу не забыть.
in>>str;
printf("Recived %s",str);
delete [] str;
str=0;

То есть, ты всё правильно вызвал то.

Значит, дело в содержимом in - копай )

Например, первый байт в потоке - 0x00, тогда строка будет выглядеть для printf пустой
Zizilk
А как начать писать со следующего байта?)

Затык скорее всего именно в выводе, ща проверил количество байт в сокете когда приходит сообщение байт столько же сколько и ушло.

хотя наверно перед строчкой, перед тем как выводить добавлю что-нить, чтоб было не нулевым
Алексей1153
Тут дело больше в том, что байты то ты можешь обрабатывать как хочешь, но для перевода в строковый вид тебе их надо сначала... перевести в строковый вид ))

например, массив содержит
unsigned char arr[]={0x00,0x00,0x11,0x22,0x33,0x44};


после форматирования в строку, содержимое последней должно быть, наприсер, таким

char* str="00 00 11 22 33 44";
//в байтовом представлении это
//unsigned char arr[]={0x30,0x30,0x20,  0x30,0x30,0x20,  0x31,0x31,0x20,
//        0x32,0x32,0x20,  0x33,0x33,0x20,  0x34,0x34,0x00};

ощущаешь разницу?
Zizilk
чего-то совсем запутался(... :(

Просто пересылаю из php клиента безобидную строчку "hi".

И не пойму как добраться(.

В примере который который есть поставляется вместе с креатором, там всё тоже самое, только из потока in заносится в QString и потом выводится в лейбл(там гуишное).
А если так, то как-то сложно всё получается... Я явно, что-то делаю не так.
Ps а как вывести Qstring переменную в консоль?
Алексей1153
Цитата(Zizilk @ 31.7.2010, 1:12) *
Просто пересылаю из php клиента безобидную строчку "hi".

ну, не знаю, подождём тех, кто силён в этом классе :)

Цитата(Zizilk @ 31.7.2010, 1:12) *
Ps а как вывести Qstring переменную в консоль?

оператором >> попробуй
Zizilk
Ничего не понятно. затык как раз с in, тк я пробовал выводить через дебаг Qstring всё равно нулевая строка
Алексей1153
в доке:
Example (write binary data to a stream):

QFile file("file.dat");
file.open(QIODevice::WriteOnly);
QDataStream out(&file);   // we will serialize the data into the file
out << QString("the answer is");   // serialize a string
out << (qint32)42;        // serialize an integer

//-----------------------

Example (read binary data from a stream):

QFile file("file.dat");
file.open(QIODevice::ReadOnly);
QDataStream in(&file);    // read the data serialized from the file
QString str;
qint32 a;
in >> str >> a;           // extract "the answer is" and 42


попробуй так - получится ли ?
Zizilk
по нулям
Алексей1153
Что значит по нулям )) Содержимое "str" и "a" после последней строчки чему равно ?
Zizilk
a не делал, только со стр(там код фактически такойже то к с функцией open)
содержимое str null
Алексей1153
Ну не знаю, у меня всё чётко прочиталось - строка и 42.
Zizilk
Я не знаю, может это изза того, что данные получаю из PHP, и там какой-то другой станадрт
(
Алексей1153
Наверное, там юникод, тогда символ может состоять из нескольких байтов, а первым байтом может оказаться 0. А пытаешьсчя ты считать ASCIIz-строку. Вот и происходит так - пустая строка.

Как бороться - не знаю(
Zizilk
Исходник PHP в ansi кодировке, так что скорее всего отправляет тоже анси (лишнее подтверждение тому, что hi который отправляю весит 2 байта)
Zizilk
Боюсь дело не в потоке, а в сокете...
При поптыки читать из сокета сервер крашится...

нашёл ошибку, Я пытался в 1 байт засунуть 2+ байтов.... :blush2:
Как давно после PHP на C++ не программил.
Поэтому там Qstring и использовали...
Алексей1153
Цитата(Zizilk @ 1.8.2010, 2:57) *
Я пытался в 1 байт засунуть 2+ байтов

это как так
Zizilk
в Char который там использовал пытался запихнуть строку длиной больше 1-го байта
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Форум IP.Board © 2001-2022 IPS, Inc.