Qt的tcp通信,QTcpServer服务端收不到客户端发送的数据,请帮忙看看
想达到目标:客户端向服务端发送消息,服务端根据接收到的消息,给客户端返回不同的消息,
问题:
服务端的newConnectionSlot()槽函数已经执行,但是收数据的DataReceived()槽函数没有进去。
疑问:
有没有可能执行到connect DataReceived()槽函数的时候,QTcpSocket的readyRead()信号早已经发出来了...,自然connect也没有用了。
客户端头文件
#ifndef _CLIENT_H
#define _CLIENT_H
#include <QObject>
#include <QTcpSocket>
#include <QString>
class Client : public QObject
{
Q_OBJECT
public:
explicit Client(QObject *parent=0);
~Client();
static Client* GetInstance();
void NewConnect(); //连接服务器
private slots:
void ReadMessage(); //接收数据
void DisplayError(QAbstractSocket::SocketError); //显示错误
private:
void Init();
private:
static Client *m_pInstance;
QTcpSocket *m_pTcpSocket;
QString m_strMessage; //存放从服务器接收到的字符串
quint16 m_qiBlockSize; //存放文件的大小信息
};
#endif // _CLIENT_H
客户端源文件
#include "client.h"
#include <QDebug>
Client* Client::m_pInstance=0;
Client::Client(QObject *paren) : QObject(paren)
{
m_pTcpSocket=NULL;
Init();
}
Client::~Client()
{
}
Client* Client::GetInstance()
{
if(0==m_pInstance)
{
m_pInstance= new Client;
}
return m_pInstance;
}
void Client::Init()
{
qDebug()<<"Client::Init";
m_pTcpSocket = new QTcpSocket(this);
//当有数据到来时发出readyRead()信号,执行读取数据的readMessage()函数
connect(m_pTcpSocket,SIGNAL(readyRead()),this,SLOT(ReadMessage()));
//当出现错误时发出error()信号,执行displayError()槽函数
connect(m_pTcpSocket,SIGNAL(error(QAbstractSocket::SocketError)),
this,SLOT(DisplayError(QAbstractSocket::SocketError)));
}
void Client::NewConnect()
{
qDebug()<<"Client::NewConnect";
m_qiBlockSize = 0; //初始化其为0
m_pTcpSocket->abort(); //取消已有的连接
QString l_strHostIp("192.168.1.100"),l_strHostPort("6666");
//发送数据
QByteArray l_baBlock;//用于暂存我们要发送的数据
QDataStream l_dsOut(&l_baBlock,QIODevice::WriteOnly); //使用数据流写入数据
l_dsOut.setVersion(QDataStream::Qt_4_6);//设置数据流的版本,客户端和服务器端使用的版本要相同
l_dsOut<<(quint16)0;//预留出来保存字符串的长度
l_dsOut<<tr("msg from client1");//文件内容
l_dsOut.device()->seek(0);//将流指针调整到头
l_dsOut<<(quint16)(l_baBlock.size()-sizeof(quint16));//将字符串的长度放在流前面预留的位置
m_pTcpSocket->write(l_baBlock);
//连接服务器
m_pTcpSocket->connectToHost(l_strHostIp,l_strHostPort.toInt());//连接到主机,这里从界面获取主机地址和端口号
}
void Client::ReadMessage()
{
qDebug()<<"Client::ReadMessage1";
QDataStream l_qdsIn(m_pTcpSocket);
l_qdsIn.setVersion(QDataStream::Qt_4_6); //设置数据流版本,这里要和服务器端相同
quint16 l_iTemp;
if(m_qiBlockSize==0) //如果是刚开始接收数据
{
qDebug()<<"Client::m_qiBlockSize==0";
//判断接收的数据是否有两字节,也就是文件的大小信息
//如果有则保存到blockSize变量中,没有则返回,继续接收数据
if(m_pTcpSocket->bytesAvailable() < (int)sizeof(quint16))
{
qDebug()<<"ReadMessage: m_pTcpSocket->bytesAvailable<(int)sizeof(quint16) when m_qiBlockSize=0";
return;
}
l_qdsIn >> m_qiBlockSize;
l_qdsIn >> l_iTemp;
}
qDebug()<<"m_qiBlockSize:"<<m_qiBlockSize;
qDebug()<<"l_iTemp:"<<l_iTemp;
qDebug()<<"bytesAvailable:"<<m_pTcpSocket->bytesAvailable();
if(m_pTcpSocket->bytesAvailable() < m_qiBlockSize)
{
qDebug()<<"ReadMessage: m_pTcpSocket->bytesAvailable() < m_qiBlockSize";
return;
}
//如果没有得到全部的数据,则返回,继续接收数据
l_qdsIn >> m_strMessage; //将接收到的数据存放到变量中
qDebug()<<"ReadMessage: m_strMessage:"<<m_strMessage;
//ui->messageLabel->setText(message);//显示接收到的数据
}
void Client::DisplayError(QAbstractSocket::SocketError)
{
qDebug() <<"SocketError is:"<<m_pTcpSocket->errorString(); //输出错误信息
}
服务端头文件
#ifndef _SERVER_H
#define _SERVER_H
#include <QTcpServer>
#include <QTcpSocket>
#include <QObject>
#include <QString>
class Server : public QObject
{
Q_OBJECT
public:
explicit Server(QObject *parent=0);
~Server();
static Server* GetInstance();
void Init();
private slots:
void newConnectionSlot();
void DataReceived();
private:
static Server *m_pInstance;
QTcpServer *m_pTcpServer;
QTcpSocket *m_pTcpSocket;
QString m_strMessage; //存放从服务器接收到的字符串
quint16 m_qiBlockSize; //存放文件的大小信息
};
#endif // _SERVER_H
服务端源文件
--------------------编程问答-------------------- 搞明白了,
#include "server.h"
#include <QDebug>
#include <QTcpSocket>
Server* Server::m_pInstance=0;
Server::Server(QObject *paren) : QObject(paren)
{
m_pTcpServer=NULL;
m_pTcpSocket=NULL;
}
Server::~Server()
{
}
Server* Server::GetInstance()
{
if(0==m_pInstance)
{
m_pInstance= new Server;
}
return m_pInstance;
}
void Server::Init()
{
qDebug()<<"Server::Init";
m_pTcpServer = new QTcpServer(this);
if(!m_pTcpServer->listen(QHostAddress::Any,6666))
{
//监听本地主机的6666端口,如果出错就输出错误信息,并关闭
qDebug()<<"Init: fail to listen 6666";
delete m_pTcpServer;
m_pTcpServer=NULL;
return ;
}
connect(m_pTcpServer,SIGNAL(newConnection()),this,SLOT(newConnectionSlot()));
qDebug()<<"success::Init";
}
void Server::newConnectionSlot()
{
qDebug()<<"Server::newConnectionSlot1";
m_pTcpSocket = m_pTcpServer->nextPendingConnection();//获取已经建立的连接的子套接字
if(NULL==m_pTcpSocket)
{
qDebug()<<"newConnectionSlot: m_pTcpSocket is null";
return ;
}
m_qiBlockSize=0;
m_strMessage="";
//关联接受客户端发来数据的槽
this->connect(m_pTcpSocket, SIGNAL(readyRead()),this, SLOT(DataReceived()));
connect(m_pTcpSocket, SIGNAL(disconnected()), m_pTcpSocket, SLOT(deleteLater()));
qDebug()<<"newConnectionSlot:: successful!!!";
}
void Server::DataReceived()
{
qDebug()<<"Server::DataReceived";
QDataStream l_qdsIn(m_pTcpSocket);
l_qdsIn.setVersion(QDataStream::Qt_4_6); //设置数据流版本,这里要和服务器端相同
if(m_qiBlockSize==0) //如果是刚开始接收数据
{
//判断接收的数据是否有两字节,也就是文件的大小信息
//如果有则保存到blockSize变量中,没有则返回,继续接收数据
if(m_pTcpSocket->bytesAvailable() < (int)sizeof(quint16))
{
qDebug()<<"DataReceived: m_pTcpSocket->bytesAvailable<(int)sizeof(quint16) when m_qiBlockSize=0";
return;
}
l_qdsIn >> m_qiBlockSize;
}
qDebug()<<"m_qiBlockSize:"<<m_qiBlockSize;
qDebug()<<"bytesAvailable:"<<m_pTcpSocket->bytesAvailable();
if(m_pTcpSocket->bytesAvailable() < m_qiBlockSize)
{
qDebug()<<"DataReceived: m_pTcpSocket->bytesAvailable() < m_qiBlockSize";
return;
}
//如果没有得到全部的数据,则返回,继续接收数据
l_qdsIn >> m_strMessage; //将接收到的数据存放到变量中
qDebug()<<"DataReceived:: success to get msg["<<m_strMessage<<"] from client, so return msg";
//给客户端返回数据
QByteArray l_baBlock;//用于暂存我们要发送的数据
QDataStream l_dsOut(&l_baBlock,QIODevice::WriteOnly); //使用数据流写入数据
l_dsOut.setVersion(QDataStream::Qt_4_6);//设置数据流的版本,客户端和服务器端使用的版本要相同
l_dsOut<<(quint16)0;//预留出来保存字符串的长度
if(m_strMessage.contains("client1"))
{
l_dsOut<<(quint16)9527;
}
else
{
l_dsOut<<(quint16)8888;
}
l_dsOut<<tr("hello Tcp!!!");//文件内容
l_dsOut.device()->seek(0);//将流指针调整到头
l_dsOut<<(quint16)(l_baBlock.size()-2*sizeof(quint16));//将字符串的长度放在流前面预留的位置
m_pTcpSocket->write(l_baBlock);
m_pTcpSocket->disconnectFromHost();//释放接收到的socket
qDebug()<<"DataReceived:: successful!!!";
}
客户端write应该在connectToHost之后就可以了 --------------------编程问答-------------------- 。。。。这么快。厉害。 --------------------编程问答-------------------- 除
补充:移动开发 , Qt