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(); }