QT 使用QTcpServer QTcpSocket 建立TCP服务器端 和 客户端

1。  如图客户端连接server后,server发送“hello tcp“ 给客户端

 

2. 实例代码

-----------------------------------  server端 -----------------------------------------

修改工程文件.pro, QT += network, 添加net模块

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QtNetwork>

namespace Ui {
class Widget;
}
class Widget : public QWidget
{
    Q_OBJECT    
public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();    
private:
    Ui::Widget *ui;
    QTcpServer *tcpServer;
public slots:
    void sendMessages();
};

#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QtGui>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    tcpServer = new QTcpServer(this);
    if( !tcpServer->listen(QHostAddress::LocalHost, 13888) )
    {   //监听本地主机的13888端口,如果出错就输出错误信息,并关闭
        qDebug() << tcpServer->errorString();
        close();
    }
    //连接信号和相应槽函数
    connect(tcpServer, SIGNAL(newConnection()), this, SLOT(sendMessages()));
}

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

void Widget::sendMessages()
{
    QByteArray block;   //用于暂存我们要发送的数据
    QDataStream out(&block, QIODevice::WriteOnly);  //使用数据流写入数据
    out.setVersion(QDataStream::Qt_4_7);
    out << (quint16) 0;
    out << tr("hello tcp");
    out.device()->seek(0);
    out << (quint16) (block.size() - sizeof(quint16));

    //获取已经建立的连接的子套接字
    QTcpSocket *clientConnection = tcpServer->nextPendingConnection();
    connect(clientConnection, SIGNAL(disconnected()), clientConnection, SLOT(deleteLater()));
    /*clientConnection->disconnectFromHost();它表示当发送完成时就会断开连接,
     *这时就会发出disconnected()信号,
     *而最后调用deleteLater()函数保证在关闭连接后删除该套接字clientConnection。
    */
    clientConnection->write(block);
    clientConnection->disconnectFromHost();
    ui->statusLabel->setText("Send message successfil");
}

 

---------------------------------------- Client 端 ----------------------------------

clientwidget.h

#ifndef CLIENTWIDGET_H
#define CLIENTWIDGET_H

#include <QWidget>
#include <QtNetwork>
#include <QtGui>

namespace Ui {
class clientWidget;
}

class clientWidget : public QWidget
{
    Q_OBJECT
    
public:
    explicit clientWidget(QWidget *parent = 0);
    ~clientWidget();   

private slots:
    void newConnect();   //连接服务器
    void readMessage();  //接收数据
    void displayError(QAbstractSocket::SocketError); //显示错误

private:
    Ui::clientWidget *ui;
    QTcpSocket *tcpSocket;
    QString message; //存放从服务器接收到的字符串
    quint16 blockSize; //存放文件的大小信息
};

#endif // CLIENTWIDGET_H

clientwidget.cpp

#include "clientwidget.h"
#include "ui_clientwidget.h"
#include <QtDebug>

clientWidget::clientWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::clientWidget)
{
    ui->setupUi(this);

    tcpSocket = new QTcpSocket(this);
    connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(readMessage()));
    connect(tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)),
            this, SLOT(displayError(QAbstractSocket::SocketError)));
    /*这里关联了tcpSocket的两个信号,
     *当有数据到来时发出readyRead()信号,我们执行读取数据的readMessage()函数。
     *当出现错误时发出error()信号,我们执行displayError()槽函数。
    */
    connect(ui->linkButton, SIGNAL(clicked()), this, SLOT(newConnect()));
}

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

void clientWidget::newConnect()
{
    blockSize = 0;
    tcpSocket->abort(); //取消已有的连接
    tcpSocket->connectToHost(ui->hostLineEdit->text(),
                             ui->portLineEdit->text().toInt());
     //连接到主机,这里从界面获取主机地址和端口号
}

void clientWidget::readMessage()
{
    QDataStream in(tcpSocket);
    in.setVersion(QDataStream::Qt_4_7);
    if( blockSize == 0 )
    {
        //判断接收的数据是否有两字节,也就是文件的大小信息
        //如果有则保存到blockSize变量中,没有则返回,继续接收数据
        if( tcpSocket->bytesAvailable() < (int)sizeof(quint16) )
            return;
        in >> blockSize;
    }
    //如果没有得到全部的数据,则返回,继续接收数据
    if( tcpSocket->bytesAvailable() < blockSize )
        return;
    in >> message;  //将接收到的数据存放到变量中
    ui->messageLabel->setText(message);
}

void clientWidget::displayError(QAbstractSocket::SocketError)
{
    qDebug() << tcpSocket->errorString();
}





 

posted @ 2013-08-23 13:35  今晚打酱油_  阅读(3668)  评论(0编辑  收藏  举报