LINUX.ORG.RU

Qt: TCP соединение


0

0

Не передаются данные от клиента к серверу.

------------ Сервер:

MyEth::MyEth(int Port) {

	tcpSrv = new QTcpServer(this);
	if(!tcpSrv->listen(QHostAddress::Any, Port)){
		qDebug() << "ERROR: Unable to Start TCP Connection: " +
                                                  tcpSrv->errorString();
		tcpSrv->close();
		return;
	}
	connect(tcpSrv, SIGNAL(newConnection()), this, SLOT(serverConnection()));
}

void MyEth::serverConnection() {
	tcpClt = tcpSrv->nextPendingConnection();
	connect(tcpClt, SIGNAL(readyRead()), this, SLOT(rcvFromEth()));
}

void MyEth::rcvFromEth() {
#ifdef __DEBUG
	qDebug("Read Data");
#endif
	QTcpSocket *tcpClt =   (QTcpSocket *) sender();
	QDataStream in(tcpClt);
	in.setVersion(QDataStream::Qt_4_6);
	QString str;
	in >> str;
	qDebug() << str;
}
Connect происходит, приема данных не происходит, даже в слот не попадает.

------------ Клиент:

MyEth::MyEth(const QString &hostIP, int Port) {

	tcpClt = new QTcpSocket(this);
	do {
		tcpClt->connectToHost(hostIp, Port);
	} while (!tcpClt->waitForConnected(1000));
sendToEth();
}

void MyEth::sendToEth() {
	QByteArray byteArr;
	QDataStream out(&byteArr, QIODevice::WriteOnly);
	out.setVersion(QDataStream::Qt_4_6);
	out << " Что-то здесь... ";
	int nn;
	if( (nn = tcpClt->write(byteArr)) == -1)
		qDebug() << "ERROR";
	else
		qDebug() << nn;


}
Передача типа проходит - nn печатается (причем, реальное кол-во байт - 5 ?). Почему-то, когда перед sendToEth() ставлю задержку, а в это время сервер рублю tcpSrv->close(), передача все равно проходит ???


>Connect происходит, приема данных не происходит, даже в слот не попадает.

connect(tcpClt, SIGNAL(readyRead()), this, SLOT(rcvFromEth()), Qt::DirectConnection);

а так?

antony986
()
Ответ на: комментарий от antony986

Так а куда клиент их пихает тогда ? Ведь должен же подвиснуть - TCP.

drZlo
() автор топика
Ответ на: комментарий от anonymous

Нужно. QTcpSocket буферизован. В случае буферизованного сокета QAbstractSocket::writeData() пишет данные в свой внутренний FIFO, а QIODevice::write(), которую ты дергаешь, вызывает именно writeData(). Поэтому нужно либо дожидаться записи данных в платформенный сокет с помощью QAbstractSocket::waitForBytesWritten() (который испоьзует select(2) с указанным таймаутом), либо использовать event loop и обрабатывать сигнал QIODevice::bytesWritten().

См. исходный код QTcpSocket::QTcpSocket(), QAbstractSocket::writeData() и QIODevice::write().

anonymous
()
Ответ на: комментарий от anonymous

> А главное, куда его вставлять ?

Ты что, совсем тупой?

anonymous
()
Ответ на: комментарий от anonymous

> В случае буферизованного сокета QAbstractSocket::writeData() пишет данные в свой внутренний FIFO

Так в доках нигде не сказано, что они оба (AbstractSocket и TcpSocket) асинхронны, в отличие от Http/Ftp.

Хотя такой подляники вполне логично ожидать.

LamerOk ★★★★★
()
Ответ на: комментарий от anonymous

Интересует 2 вопроса:

1. Почему это в книжках (Шлее «Проф прог Qt», Бланшет) не описано ? Тем более, почему нет примера применения и http://doc.trolltech.com/4.6/network-fortuneserver.html и http://doc.trolltech.com/4.6/network-blockingfortuneclient.html ? Что заранее неправильные примеры приводят ?...

2.

внутренний FIFO


Как определить глубину и изменить ?

drZlo
() автор топика
Ответ на: комментарий от anonymous

Да, и еще, что делать после получения QIODevice::bytesWritten() или срабатывания QAbstractSocket::waitForBytesWritten() ? Сейчас я их не обрабатываю и что ? не дождался клиент отправки данных (их не много), и повис (использую event loop), он же соединения не рвет ?Почему сервер не принимает?

drZlo
() автор топика
Ответ на: комментарий от drZlo

М-да, сигнал QIODevice::bytesWritten() я не получаю, значит передачи в девайс нет ? Почему это может быть ?

drZlo
() автор топика
Ответ на: комментарий от drZlo

event loop у тебя в программе есть, чтобы ты мог получать уведомления?

hint1:QTcpServer без event loop'а не работает (точнее, нужно самому дожидаться нового подключения с помощью QTcpServer::waitForNewConnection()).
hint2:event loop - это, например, вызов QCoreApplication::exec() или QApplication::exec() в одном потоке с main().

anonymous
()
Ответ на: комментарий от anonymous

> event loop у тебя в программе есть

Нет и не надо - приложение консольное.

QTcpServer без event loop'а не работает (точнее, нужно самому дожидаться нового подключения с помощью QTcpServer::waitForNewConnection()).


Как это не работает ?
The non-blocking alternative is to connect to the newConnection() signal
Сигнал принимается.

???

drZlo
() автор топика
Ответ на: комментарий от drZlo

>Нет и не надо - приложение консольное.

Для приложений без GUI используется QCoreApplication::exec() в таких случаях.

anonymous
()
Ответ на: комментарий от anonymous

Это не то ? У меня ща так:


int main(int argc, char *argv[])
{
	QCoreApplication app(argc, argv);

        MyConsole cons;

	return app.exec();
}

А куда здесь QCoreApplication::exec() поместить ?

drZlo
() автор топика
Ответ на: комментарий от drZlo

А не может быть такого из-за того, что клиент и сервер на одном компе ? Т.е. через петлю конекчусь 127.0.0.1.

drZlo
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.