您的位置:首页 > 理论基础 > 计算机网络

C++ Qt5 TcpSocket网络通讯(传输数据块大小值,防止没有传送完整)

2016-04-04 22:31 603 查看
服务端

datareceiver.pro

#-------------------------------------------------
#
# Project created by QtCreator 2016-04-04T20:32:59
#
#-------------------------------------------------

QT       += core gui
QT       +=network
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = datareceiver
TEMPLATE = app

SOURCES += main.cpp\
mainwindow.cpp

HEADERS  += mainwindow.h

FORMS    += mainwindow.ui
mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include<QTcpSocket>
#include<QDataStream>
#include<QByteArray>
#include<QTcpServer>
#include<QString>
namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
Q_OBJECT
private:
QTcpServer * m_server;
QTcpSocket * m_socket;
qint64 bytesreceived;
qint64 bytestotal;//|数据大小 总共一起
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();

private slots:
void on_btn_close_clicked();
void on_conned();
void on_disconned();
void on_readyread();
private:
Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H
mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<QHostAddress>
#include<QMessageBox>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
this->m_server=new QTcpServer(this);
this->bytesreceived=0;
m_server->listen(QHostAddress::Any,520);
connect(this->m_server,SIGNAL(newConnection()),this,SLOT(on_conned()));
/************设置ui************/
this->ui->btn_close->hide();
}

MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_conned()
{
this->m_socket=this->m_server->nextPendingConnection();
/******更新ui*********/
this->ui->btn_close->show();
this->ui->label_status->setText("客户端已经连接本机!");
connect(this->m_socket,SIGNAL(disconnected()),this,SLOT(on_disconned()));
connect(this->m_socket,SIGNAL(readyRead()),this,SLOT(on_readyread()));
}
/******关闭socket后*******/
void MainWindow::on_disconned()
{
this->ui->btn_close->hide();
this->ui->label_status->setText("已断开!");
this->m_socket=0;
this->bytesreceived=0;

}
void MainWindow::on_btn_close_clicked()
{
if(this->m_socket)
{
this->m_socket->close();
}

}
void MainWindow::on_readyread()
{
/******
相应一次 readyRead是根据情况来的
有时候 一次性 就发送完了 所有数据
有时候 数据很多 就响应了 很多次  才就收完数据!
*******/

QDataStream dts(this->m_socket);
/*********bytesreceived为0就为第一次接收 ************/
if(this->bytesreceived==0)
{
//|如果是第一次接收
if(this->m_socket->bytesAvailable()>=sizeof(qint64))
{
//|如果发送完了 总大小数据块

dts>>this->bytestotal;
this->bytesreceived+=sizeof(qint64);
//      QMessageBox::about(this,"x",QString::number(sizeof(qint64)));//8 bit
QMessageBox::about(this,"x",QString::number(this->bytestotal));
QMessageBox::about(this,"x",QString::number(this->m_socket->bytesAvailable()));
if(this->bytesreceived+this->m_socket->bytesAvailable()==this->bytestotal)
{
//|如果第一次响应(一次性就发送了所有数据)就接收
QString data;
dts>>data;
this->ui->textBrowser->append(QString::number(this->bytestotal)+"----"+data+"<br/>");
/*********** 此次数据发送动作完毕*********清除一些成员属性*****方便于不断开连接情况下 第二次发送数据******/
this->bytesreceived=0;
}
}
}else{
/*******bytesreceived不为0 则不为第一次 响应(这个文件很大,或者 网络状态不是很好)*********/
/*****************
* 每次就会响应这里 直到 数据接收够了 为止
******************/
if(this->bytesreceived+this->m_socket->bytesAvailable()==this->bytestotal)
{
QString data;
dts>>data;
this->ui->textBrowser->append(QString::number(this->bytestotal)+"----"+data+"<br/>");
/*********** 此次数据发送动作完毕*********清除一些成员属性**方便于不断开连接情况下 第二次发送数据*********/
this->bytesreceived=0;
}

}
}
main.cpp

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();

return a.exec();
}
mainwindow.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>553</width>
<height>447</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralWidget">
<widget class="QTextBrowser" name="textBrowser">
<property name="geometry">
<rect>
<x>20</x>
<y>90</y>
<width>521</width>
<height>192</height>
</rect>
</property>
</widget>
<widget class="QPushButton" name="btn_close">
<property name="geometry">
<rect>
<x>150</x>
<y>30</y>
<width>80</width>
<height>20</height>
</rect>
</property>
<property name="text">
<string>断开</string>
</property>
</widget>
<widget class="QLabel" name="label_status">
<property name="geometry">
<rect>
<x>20</x>
<y>30</y>
<width>91</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>未连接</string>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>553</width>
<height>22</height>
</rect>
</property>
</widget>
<widget class="QToolBar" name="mainToolBar">
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<widget class="QStatusBar" name="statusBar"/>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>


客户端

datasender.pro

#-------------------------------------------------
#
# Project created by QtCreator 2016-04-04T20:14:45
#
#-------------------------------------------------

QT       += core gui
QT       +=network
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = datasender
TEMPLATE = app

SOURCES += main.cpp\
mainwindow.cpp

HEADERS  += mainwindow.h

FORMS    += mainwindow.ui


mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include<QTcpSocket>
#include<QDataStream>
#include<QByteArray>
#include <QMainWindow>
#include<QString>
namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
Q_OBJECT
private:
QTcpSocket * m_socket;
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();

private slots:
void on_btn_conn_clicked();
void on_connected();
void on_discon();
void on_btn_send_clicked();

private:
Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H


mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
/*****TcpSocket对象******/
this->m_socket=new QTcpSocket(this);
this->ui->btn_disconn->hide();

}

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

void MainWindow::on_btn_conn_clicked()
{
this->m_socket->connectToHost("127.0.0.1",520);
connect(this->m_socket,SIGNAL(connected()),this,SLOT(on_connected()));
connect(this->m_socket,SIGNAL(disconnected()),this,SLOT(on_discon()));
}
void MainWindow::on_connected()
{
/******修改ui********/
this->ui->btn_disconn->show();
this->ui->btn_conn->hide();
this->ui->label_status->setText("连接成功!");
/*********/
}
void MainWindow::on_discon()
{
/******修改ui********/
this->ui->btn_disconn->hide();
this->ui->btn_conn->show();
this->ui->label_status->setText("断开");
}

void MainWindow::on_btn_send_clicked()
{
/********qint64 数据大小<<QString数据************/
QByteArray data;
QDataStream dts(&data,QIODevice::WriteOnly);
QString text=this->ui->textEdit->toPlainText();
dts<<(qint64)0<<text;
dts.device()->seek(0);
dts<<(qint64)data.size();
this->m_socket->write(data);
}


main.cpp

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();

return a.exec();
}


mainwindow.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>496</width>
<height>342</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralWidget">
<widget class="QPushButton" name="btn_conn">
<property name="geometry">
<rect>
<x>40</x>
<y>20</y>
<width>80</width>
<height>20</height>
</rect>
</property>
<property name="text">
<string>连接服务器</string>
</property>
</widget>
<widget class="QPushButton" name="btn_disconn">
<property name="geometry">
<rect>
<x>150</x>
<y>20</y>
<width>80</width>
<height>20</height>
</rect>
</property>
<property name="text">
<string>断开</string>
</property>
</widget>
<widget class="QLabel" name="label_status">
<property name="geometry">
<rect>
<x>60</x>
<y>70</y>
<width>81</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>断开</string>
</property>
</widget>
<widget class="QTextEdit" name="textEdit">
<property name="geometry">
<rect>
<x>40</x>
<y>120</y>
<width>361</width>
<height>70</height>
</rect>
</property>
</widget>
<widget class="QPushButton" name="btn_send">
<property name="geometry">
<rect>
<x>30</x>
<y>200</y>
<width>80</width>
<height>20</height>
</rect>
</property>
<property name="text">
<string>发送</string>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>496</width>
<height>22</height>
</rect>
</property>
</widget>
<widget class="QToolBar" name="mainToolBar">
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<widget class="QStatusBar" name="statusBar"/>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: