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);
}
QAbstractSocket Win - > Linux
Сервер пишется под Ubuntu. В общих чертах:
Код:
Код:
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);
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);
Запуск в Virtual Box local networking. В ubuntu поднимал интерфейс ifconfig etho 192.168.0.2 netmask 255.255.255.0.
Два вопроса:
1) Почему клиент не переходит в стадию Connected?
2) Почему клиент получает от сервера обнулённые данные?
Код:
soc->waitForConnected();
Код:
soc->connectToHost(QString::fromStdString(addr),port);
UPD: Не, ни фига. Оно то работает, то не работает.
UPD1:
Убрал создание сокета из потока. Там какой-то трабл был с таймером, принадлежащему сокету. Подозреваю, что он не создавался или не убивался(иногда всплывало сообщение о том, что нельзя создать дочерний объект из иного треда или убить таймер по той же причине). Успешно получены данные в 80% запусках программы. В чём истинная причина неполадок так и не понял.
Версия Qt? В чем собираешь? Покажи больше кода.
Код:
#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";
}
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";
}
Код:
class MyThread : public QThread
{
public:
void run();
};
void MyThread::run()
{
QTcpSocket socket;
// connect QTcpSocket's signals somewhere meaningful
...
socket.connectToHost(hostName, portNumber);
exec();
}
{
public:
void run();
};
void MyThread::run()
{
QTcpSocket socket;
// connect QTcpSocket's signals somewhere meaningful
...
socket.connectToHost(hostName, portNumber);
exec();
}
И exit(); потом для завершения потока
Код:
#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);
};
#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);
};
Код:
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";
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 (из примеров) клиент/сервер у тебя норм собираются и работают?
И ещеб я переделал (хз как у тебя оформлен reply) добавил бы ему методы для адекватной передачи по сети, а то кастинг меня както смущает.
Reply метод никак не добавить, эта структура потом используется в демоне на Си, там всего два поля типа инта. Сервер и клиент собираются нормально, там какая-то цитата должна приходить, да?
Код:
--- if (result == -1)
+++ if (result == -1 || result <> sizeof(struct blahblah))
+++ if (result == -1 || result <> sizeof(struct blahblah))