首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 移动开发 > QT开发 >

用QTcpSocket作客户端用来测试TCP,但不能接收数据,求指教

2012-12-25 
用QTcpSocket做客户端用来测试TCP,但不能接收数据,求指教!#include QMessageBox#include widget.h#inc

用QTcpSocket做客户端用来测试TCP,但不能接收数据,求指教!
#include <QMessageBox>
#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    this->setFixedSize( this->width (),this->height ()); //固定窗口大小
    TcpSocket = new QTcpSocket(this);
    connect(ui->ConnectBtn,SIGNAL(clicked()),this,SLOT(Connect()));
    connect(ui->StopBtn,SIGNAL(clicked()),this,SLOT(Stop()));
    connect(ui->ClearReceiveBtn,SIGNAL(clicked()),this,SLOT(ClearReceive()));
    connect(ui->ClearSendBtn,SIGNAL(clicked()),this,SLOT(ClearSend()));
    connect(ui->SendBtn,SIGNAL(clicked()),this,SLOT(Send()));
    connect(TcpSocket,SIGNAL(readyRead()),this,SLOT(ReadMessage()));
    connect(TcpSocket,SIGNAL(error(QAbstractSocket::SocketError)),
             this,SLOT(displayError(QAbstractSocket::SocketError)));
}

Widget::~Widget()
{
    delete ui;
}


void Widget::displayError(QAbstractSocket::SocketError)
{
    qDebug() << TcpSocket->errorString(); //输出错误信息
}

void Widget::ReadMessage()
{
    qDebug("Read");
    if(TcpSocket->waitForConnected(30000)){
    QString Msg;
    QByteArray qba = TcpSocket->readAll();
    Msg=QVariant(qba).toString();
    ui->Receive_textBrowser->append(Msg);}
}

void Widget::Connect()
{
  //  BlockSize = 0; //初始化其为0
    TcpSocket->abort(); //取消已有的连接
    TcpSocket->connectToHost(ui->Remote_IP_lineEdit->text(),
                               ui->Remote_Port_lineEdit->text().toInt());
    ui->ConnectBtn->setEnabled(false);
    ui->StopBtn->setEnabled(true);
}

void Widget::Stop()
{
    TcpSocket->close();
    qDebug("socket break");
    ui->StopBtn->setEnabled(false);
    ui->ConnectBtn->setEnabled(true);
}

void Widget::Send()
{
    qDebug("send message");
    int length = 0;
    QString Msg= ui->SendMsg_lineEdit->text();
    if((length = TcpSocket->write(Msg.toStdString().c_str(),strlen(Msg.toStdString().c_str()))) != Msg.length())
    {
        qDebug("send fail");
    }
    qDebug("%d", length);
    qDebug()<< Msg;
}

void Widget::ClearSend()
{
    ui->SendMsg_lineEdit->setText ("");
}

void Widget::ClearReceive()
{
    ui->Receive_textBrowser->setText("");
}


------最佳解决方案--------------------


我可以肯定的说,用你贴出的代码是没有问题的。我帮你整了一个服务器端的测试程序:


#ifndef CSERVER_H
#define CSERVER_H

#include <QtNetwork>

class CServer : public QTcpServer
{
    Q_OBJECT

public slots:
    void start()
    {
        listen(QHostAddress::Any, 20000);
    }

protected:
    void incomingConnection(int socketDescriptor)
    {
        QTcpSocket socket;

        if (socket.setSocketDescriptor(socketDescriptor))
        {
            qDebug() << "connected.";
        }

        if (socket.waitForReadyRead())
        {
            qDebug() << socket.readAll();
        }

        socket.write("hello");

        if (socket.state() == QAbstractSocket::ConnectedState)
        {
            socket.waitForDisconnected();
        }

        qDebug() << "disconnected.";
    }
};

#endif // CSERVER_H

用这个和你的客户端进行通讯,没有任何问题。
[其他解释]
唉……楼主啊……

你发送的仍然是字符串呀!这是一个很基础的问题,比如你的数据包00 00 00 00 00 06 01 03 00 1B 00 02

你按二进制形式发送,“00” = 0x00,只占一个字节。而用字符串发送“00” = 0x30 0x30,这是俩字节呀!

你说的网上的测试工具,它发的是二进制数据,和你的不一样。

先把QByteArray这个类看一下,帮助里面已经很明确的告诉你怎么用了

QByteArray ba;
 ba.resize(5);
 ba[0] = 0x3c;
 ba[1] = 0xb8;
 ba[2] = 0x64;
 ba[3] = 0x18;
 ba[4] = 0xca;


[其他解释]
你可以先看一下Qt自带的TCP示例代码
[其他解释]
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QString>
#include <QtNetwork/QTcpSocket>

namespace Ui {
    class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

private:
    Ui::Widget *ui;
    QTcpSocket *TcpSocket;
//    quint16 BlockSize;

private slots:
    void ReadMessage();
    void displayError(QAbstractSocket::SocketError);
    void Stop();
    void ClearReceive();
    void ClearSend();


    void Send();
    void Connect();
};

#endif // WIDGET_H

[其他解释]
#-------------------------------------------------
#
# Project created by QtCreator 2012-10-26T12:48:04
#
#-------------------------------------------------

QT += network

TARGET = tcp_socket
TEMPLATE = app


SOURCES += main.cpp\
        widget.cpp

HEADERS  += widget.h

FORMS    += widget.ui

[其他解释]
我发送16进制的数据给服务端,然后从服务端读取16进制的数据,能否举个例子,谢谢
[其他解释]
ReadMessage是readyRead的槽函数,而readyRead信号发射时,网络必然已经接通。为什么还要waitForConnected呢?
[其他解释]
因为我百度了说因为readyRead()不触发,加了那个函数就没有问题了,我跟踪了下,我的那个conncet的返回值是true, 我发送 00 00 00 00 00 06 01 03 00 1B 00 02 是能够发送的,但是服务端没有反应
[其他解释]
#include <QMessageBox>
#include "widget.h"
#include "ui_widget.h"


Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    this->setFixedSize( this->width (),this->height ()); //固定窗口大小
    TcpSocket = new QTcpSocket(this);
    connect(ui->ConnectBtn,SIGNAL(clicked()),this,SLOT(Connect()));
    connect(ui->StopBtn,SIGNAL(clicked()),this,SLOT(Stop()));
    connect(ui->ClearReceiveBtn,SIGNAL(clicked()),this,SLOT(ClearReceive()));
    connect(ui->ClearSendBtn,SIGNAL(clicked()),this,SLOT(ClearSend()));
    connect(ui->SendBtn,SIGNAL(clicked()),this,SLOT(Send()));
    connect(TcpSocket,SIGNAL(readyRead()),this,SLOT(ReadMessage()));
    connect(TcpSocket,SIGNAL(error(QAbstractSocket::SocketError)),
             this,SLOT(displayError(QAbstractSocket::SocketError)));
}

Widget::~Widget()
{
    delete ui;
}


void Widget::displayError(QAbstractSocket::SocketError)
{
    qDebug() << TcpSocket->errorString(); //输出错误信息
}

void Widget::ReadMessage()
{
    qDebug("Read");
    int iBytesAvailable = TcpSocket->bytesAvailable();
    while(iBytesAvailable > 0)
    {
    if(TcpSocket->isValid())
    {
        QByteArray qba = TcpSocket->readAll();
        if(!qba.isEmpty())
        {
            QString Msg;
            Msg=QVariant(qba).toString();
            ui->Receive_textBrowser->append(Msg);


        }
        else
            qDebug("read bytes count is not valid !!"); // possibly an error
    }
    else
    {
        qDebug("Socket is not valid to read data from");
        break;
    }
    iBytesAvailable = TcpSocket->bytesAvailable();
    }
}

void Widget::Connect()
{
  //  BlockSize = 0; //初始化其为0
    TcpSocket->abort(); //取消已有的连接
    TcpSocket->connectToHost(ui->Remote_IP_lineEdit->text(),
                               ui->Remote_Port_lineEdit->text().toInt());
    if (!TcpSocket->waitForConnected())
    {
        qDebug()<<"Unable to connect";
        return;
    }
    ui->ConnectBtn->setEnabled(false);
    ui->StopBtn->setEnabled(true);
}

void Widget::Stop()
{
    TcpSocket->close();
    qDebug("socket break");
    ui->StopBtn->setEnabled(false);
    ui->ConnectBtn->setEnabled(true);
}

void Widget::Send()
{
    qDebug("send message");
    int length = 0;
    QString Msg= ui->SendMsg_lineEdit->text();
    if((length = TcpSocket->write(Msg.toStdString().c_str(),strlen(Msg.toStdString().c_str()))) != Msg.length())
    {
        qDebug("send fail");
    }
    qDebug("%d", length);
    qDebug()<< Msg;
}

void Widget::ClearSend()
{
    ui->SendMsg_lineEdit->setText ("");
}

void Widget::ClearReceive()
{
    ui->Receive_textBrowser->setText("");
}

这个是最新的,还是不行
[其他解释]
你提供的信息太少了,这样问问题很难得到准确答复。“还是不行”,怎么不行了?停在哪里了?什么现象?服务器是否是先接到一个请求,然后再发送应答?服务器端也是用Qt开发的吗?有没有办法能把服务器端收到的数据打出来看看?

ReadMessage函数是没有被调用?还是调用了但结果不对?
[其他解释]
我是想用Qt做个网上的TCP测试的工具。服务端在智能数字量采集联网设备里,因为提供的资料比较少,只有产品介绍文档,里面有说设备作为服务端时,应该用到的报文协议,

运行后输入要发送的数据后,点击发送,出现一下信息: 
Starting C:\tcp_socket-build-desktop\debug\tcp_socket.exe...
send message //发送数据
35  //数据大小
"00 00 00 00 00 06 01 03 00 1B 00 02" //发送的内容

不能进入ReadMessage函数,我取过 connect(TcpSocket,SIGNAL(readyRead()),this,SLOT(ReadMessage())) 的值是true.

[其他解释]
报文协议是这样的:
事务处理标识: 2字节
协议标识: 2字节(0标识MODBUS协议)
后面字节数: 2字节
单元标识,即从设备地址1字节:内容为0-0xff


功能码: 1字节,内容为3
起始寄存器地址: 2字节,高字节在前
寄存器个数: 2字节,高字节在前(1-0x7D)
[其他解释]
对于新手来说,解决这个问题不能着急,因为你对Qt还不怎么了解,你不太好判断问题是出在报文上还是QTcpSocket的使用上,或者说是服务器端出了问题。

我的建议是,你自己用QTcpServer做一个简单的服务器端程序,配合你这个客户端进行一次测试。如果你写的服务器程序能够和你的客户端通讯,那说明,你的客户端程序是正确的。问题一定是出在传输的内容上,或是服务器那边。
[其他解释]
仔细看了一遍你的报文协议和你的Send函数,貌似你发送的是字符串,而不是二进制数据。

00 00 00 00 00 06 01 03 00 1B 00 02

这串文字是个字符串而已,它完全不是服务器想要的内容!!!!
[其他解释]
那改如何去转换?谢谢!
[其他解释]
Qt的函数只能发送char * 和 QByteArray  这两种类型啊 。
[其他解释]
QByteArray
[其他解释]
我想问下,我这个代码有没问题? 我也是参考网上的。
另外我改成了QByteArray,还是不能够接收服务端的信息。
不能进入到ReadMessage函数
[其他解释]
我试了下,客户端能发给服务端,服务端不能发给客户端,而且客户端的程序会死机,我也用网上的测试工具测试了,也一样
[其他解释]

引用:
我想问下,我这个代码有没问题? 我也是参考网上的。
另外我改成了QByteArray,还是不能够接收服务端的信息。
不能进入到ReadMessage函数

我没看出啥问题

我的建议是,你自己用QTcpServer做一个简单的服务器端程序,配合你这个客户端进行一次测试。如果你写的服务器程序能够和你的客户端通讯,那说明,你的客户端程序是正确的。问题一定是出在传输的内容上,或是服务器那边。

服务器程序也就二三十行代码,为什么不试试呢?
[其他解释]
报这样的错:C:\tcp_socket-build-desktop\debug\tcp_socket.exe exited with code -805306369
[其他解释]
别人的客户端是用C++ 或者 C#做的,会不会跟这个也有关系?两者的数据类型有差异
[其他解释]
我用网上的TCP测试工具,输入的内容和Qt做的客户端里的输入的内容是一样的,用TCP测试工具是可以读取服务端的数据的。
我修改了用16进制的格式发送和接收,情况还是一样,不能进入ReadMessage函数。
void Widget::Send()//发送数据
{
    qDebug("send message");
    int length = 0;
    QString Msg= ui->SendMsg_lineEdit->text();
    if((length = TcpSocket->write(Msg.toAscii())) != Msg.length())
    {
        qDebug("send fail");
    }
    qDebug("%d", length);
    qDebug()<< Msg.toAscii();
}

void Widget::ReadMessage()
{
    qDebug("Read");
    int iBytesAvailable = TcpSocket->bytesAvailable();
    while(iBytesAvailable > 0)
    {
        if(TcpSocket->isValid())
        {
            QByteArray temp = TcpSocket->readAll();
            QString ss=QVariant(temp).toString();
            ui->Receive_textBrowser->setText(ss);;
        }
    }
}

热点排行