QTcpSocket学习
一、涉及到的函数
监听:tcpServer->listen(QHostAddress::LocalHost, 6666)
错误信息:tcpServer->errorString()
新连接信号:connect(tcpServer, SIGNAL(newConnection()), this, SLOT(sendMessage()))
设置输出流:QByteArray block; QDataStream out(&block, QIODevice::WriteOnly);
等待数据发送完毕后删除:clientConnection->disconnectFromHost();
连接到主机:tcpSocket->connectToHost(ui->hostLineEdit->text(), ui->portLineEdit->text().toInt());
二、函数源码
tcpServer.cpp
#include "mainwindow.h" #include "ui_mainwindow.h" #include <QtNetwork> #include <QDebug> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); tcpServer = new QTcpServer(this); //使用了IPv4的本地主机地址,等价于QHostAddress("127.0.0.1") if(!tcpServer->listen(QHostAddress::LocalHost, 6666)) { qDebug()<<tcpServer->errorString(); close(); } connect(tcpServer, SIGNAL(newConnection()), this, SLOT(sendMessage())); } MainWindow::~MainWindow() { delete ui; } void MainWindow::sendMessage() { //用于暂存要发送的数据 QByteArray block; QDataStream out(&block, QIODevice::WriteOnly); //设置数据流的版本,客户端和服务器端使用的版本要相同 out.setVersion(QDataStream::Qt_4_0); 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->write(block); clientConnection->disconnectFromHost(); //等待数据发送完毕后关闭 //发送数据成功后,显示提示 ui->label->setText("send message successful!!!"); }
client.cpp
#include "mainwindow.h" #include "ui_mainwindow.h" #include <QtNetwork> #include <QDebug> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { 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))); } MainWindow::~MainWindow() { delete ui; } void MainWindow::newConnect() { //初始化数据大小信系为0 blockSize = 0; //取消已有的连接 tcpSocket->abort(); tcpSocket->connectToHost(ui->hostLineEdit->text(), ui->portLineEdit->text().toInt()); } void MainWindow::readMessage() { QDataStream in(tcpSocket); //设置数据流版本,这里要和服务器端相同 in.setVersion(QDataStream::Qt_4_6); //如果是刚开始接收数据 if(blockSize == 0) { //判断接收的数据是否大于两个字节,也就是文件的大小信息所占的空间 //如果是则保存到blockSize变量中,否则直接返回,继续接收数据 if(tcpSocket->bytesAvailable()<(int)sizeof(quint16)) return; in>>blockSize; } //如果没有得到全部的数据,则返回,继续接收数据 if(tcpSocket->bytesAvailable() < blockSize) return; //将接收到的数据存放到变量中 in>>message; //显示接收到的数据 qDebug()<<message; ui->messageLabel->setText(message); } void MainWindow::displayError(QAbstractSocket::SocketError) { qDebug()<<tcpSocket->errorString(); } void MainWindow::on_connectButton_clicked() { newConnect(); }
三、函数说明
server有一个信号槽,当建立了新的连接就发送一个字符串。
client则需要对服务器端建立连接,这时服务器不是发送了字符串嘛。就会有readyRead信号触发,然后从流中读取数据。
无欲速,无见小利。欲速,则不达;见小利,则大事不成。