当前位置:编程学习 > wap >>

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
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,