所谓网络调试助手,即软件同时支持UDP协议和TCP协议。就是可以使用UDP协议,监听端口,完成与对端设备的数据收发。同时使用TCP协议,既可以当作服务器端,监听本机主机端口,得到客户端连接信息,并管理与客户端之间的连接,可完成数据的收发;又可以当作TCP客户端,发送连接请求与远端服务器连接,可以向服务器发送数据进行请求,也能够接收到服务器给予的应答。这是网口助手最基本的功能。本文分成两篇完成。
TCP协议,传输控制协议,是一个用于数据传输的底层的网络协议,多个互联网协议包括FTP,HTTP协议都是基于TCP协议的。TCP是一个面向数据流和连接的可靠的传输协议。QTcpSocket类为TCP提供了一个接口,可以用其实现POP3、SMTP等标准的网络协议,也可以实现自定义的网络协议。连接的一端是客户端,另一端是服务器端,也就是C/S模型。
使用Qt network做一个TCP服务器,可以接收客户端的访问请求,能够传输数据。 首先创建QTcpServer类对象,用于管理服务器;调用listen方法,监听对应地址对应端口,使本主机作为服务器,使得程序能够监听某一端口的连接情况;当有客户端发出连接请求时,服务器对象会发出newConnection()信号,监听过程出错时,服务器会发出acceptError()信号;连接建立后出现错误会发出disconnected()信号,有数据来临会发出readyread()信号,当需要发送数据到客户端的时候,调用write方法即可。
与网口助手调试(链接在文末)结果如下,收发数据正常。
与Qt开发客户端测试结果如下,汉字收发正常。
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTcpserver>
#include <QNetworkInterface>
#include <QTcpSocket>
#include <QDebug>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void doProcessNewConnection();
void doProcessAcceptError(QAbstractSocket::SocketError);
void doProcessDisconnected();
void doProcessReadyRead();
// void doProcessConnect();
void on_band_Btn_clicked();
void on_tran_Btn_clicked();
private:
Ui::MainWindow *ui;
QTcpServer *myServer;
QTcpSocket *client;
QList<QTcpSocket *>arrayClient;
void Init();
};
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"
#define MAXNUM 100
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
Init();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::Init()
{
myServer = new QTcpServer(this);
this->setWindowTitle("服务器");
}
//绑定按钮槽函数
void MainWindow::on_band_Btn_clicked()
{
//方法1 :通过程序遍历网卡ip
// QList<QHostAddress>addrs = QNetworkInterface::allAddresses();
// for (int i = 0; i <addrs.length(); ++i) {
// QHostAddress addr = addrs.at(i);
// qDebug()<<addr.toString();
// if(addr.toString().contains("192.")){
// myAddr = addr.toString();
// break;
// }
// }
//方法2: 手动设置ip
QString myAddr = ui->serverIP->text();
QString myPort = ui->serverPort->text();
QString msg;
bool ret = myServer->listen(QHostAddress(myAddr),myPort.toUInt());//监听对应地址对应端口,使本主机作为服务器
if(!ret){
msg = "绑定失败!";
}
else{
msg = "绑定成功!";
ui->band_Btn->setEnabled(false);
}
ui->textEdit->append(msg);
myServer->setMaxPendingConnections(MAXNUM);//设置等待连接队列中的最大数量,默认30
connect(myServer,SIGNAL(newConnection()),this,SLOT(doProcessNewConnection()));//监听之后,新的客户端接入会触发此信号
connect(myServer,SIGNAL(acceptError(QAbstractSocket::SocketError)),
this,SLOT(doProcessAcceptError(QAbstractSocket::SocketError)));//监听过程出错会进入这个槽
}
//绑定发送按钮槽函数
void MainWindow::on_tran_Btn_clicked()
{
//获取界面ip地址和端口信息
QString ip = ui->clientIP->text();
QString port = ui->clientPort->text();
//查找对应的客户
for (int i = 0; i < arrayClient.length(); ++i) {
if(arrayClient.at(i)->peerAddress().toString() == ip){//找到对应的ip
if(arrayClient.at(i)->peerPort() == port.toUInt()){//找到对应端口
QString msg = ui->textEdit_2->toPlainText();
arrayClient.at(i)->write(msg.toUtf8());//使用utf8可以发送汉字,对方也使用utf8则可以正确接收
ui->textEdit_2->clear();
break;
}
}
}
}
void MainWindow::doProcessNewConnection()
{
client = myServer->nextPendingConnection();//建立连接,获取客户端对象
QString msg = QString("客户端[%1:%2] 连入!").arg(client->peerAddress().toString()).arg(client->peerPort());
ui->textEdit->append(msg);
arrayClient.append(client);//存储已接入的客户端
//客户端断开
connect(client,SIGNAL(disconnected()),this,SLOT(doProcessDisconnected()));//建立间接之后,监听断开信号
//读取内容
connect(client,SIGNAL(readyRead()),this,SLOT(doProcessReadyRead()));//准备接收数据
}
void MainWindow::doProcessAcceptError(QAbstractSocket::SocketError err)
{
qDebug()<<err;
}
void MainWindow::doProcessDisconnected()
{
QTcpSocket *client = (QTcpSocket *)this->sender();
QString msg = QString("客户端[%1:%2] 退出!").arg(client->peerAddress().toString()).arg(client->peerPort());
ui->textEdit->append(msg);
//删除客户端列表断开的客户端
for (int i = 0; i < arrayClient.length(); ++i) {
if(arrayClient.at(i)->peerAddress() == client->peerAddress()){
if(arrayClient.at(i)->peerPort() == client->peerPort()){
arrayClient.removeAt(i);
}
}
}
}
void MainWindow::doProcessReadyRead()
{
QTcpSocket *client = (QTcpSocket *)this->sender();
QString str1 = QString("客户端[%1:%2] 说:").arg(client->peerAddress().toString()).arg(client->peerPort());//返回客户端的ip与port
QString msg;
QString str2;
while(!client->atEnd()){
msg.append(QString(client->readAll()));//接收数据
}
str2 = QString("%1%2").arg(str1).arg(msg);
ui->textEdit->append(str2);
}
使用Qt开发Tcp客户端与服务器之间的差异很小,主要是服务器使用的类对象是由QTcpServer实例化的,而客户端的类对象是由QTcpSocket实例化的。另外一点就是客户端,连接服务器时要用到,connectToHost()方法,服务器则是要用listen监听某个端口。当连接建立之后,对于连接的管理,数据的处理几乎连信号都是一样的。
与网口调试助手测试收发数据正常
与Qt开发服务器测试收发数据正常。
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTcpSocket>
#include <QHostAddress>
#include <QDebug>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_btn_Connect_clicked();
void doProcessConnected();
void doProcessReadyRead();
void doProcessDisconnected();
void doProcessError(QAbstractSocket::SocketError);
void on_btn_Send_clicked();
private:
Ui::MainWindow *ui;
QTcpSocket *myClient;
void Init();
};
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
Init();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::Init(){
this->setWindowTitle("客户端");
myClient = new QTcpSocket(this);
}
void MainWindow::on_btn_Connect_clicked()
{
QString servIP = ui->serverIP->text();//获取用户的ip
QString servPort = ui->serverPort->text();//获取用户的端口
myClient->connectToHost(QHostAddress(servIP),servPort.toUInt());//连接服务器
connect(myClient,SIGNAL(connected()),this,SLOT(doProcessConnected()));//连接成功
connect(myClient,SIGNAL(readyRead()),this,SLOT(doProcessReadyRead()));//获取数据
connect(myClient,SIGNAL(disconnected()),this,SLOT(doProcessDisconnected()));//连接断开
connect(myClient,SIGNAL(error(QAbstractSocket::SocketError))
,this,SLOT(doProcessError(QAbstractSocket::SocketError)));//连接出错
}
//连接建立信号
void MainWindow::doProcessConnected()
{
QString msg = "服务器连接成功!";
ui->textEdit->append(msg);
ui->btn_Connect->setEnabled(false);
}
void MainWindow::doProcessReadyRead()
{
QString msg,str1,str2;
str1 = QString("服务器[%1 %2]说:").arg(myClient->peerAddress().toString()).arg(myClient->peerPort());
while (!myClient->atEnd()) {
str2.append(QString(myClient->readAll()));//接收数据
}
msg = QString("%1%2").arg(str1).arg(str2);
ui->textEdit->append(msg);
}
void MainWindow::doProcessDisconnected()
{
QString msg = "服务器退出!";
ui->textEdit->append(msg);
ui->btn_Connect->setEnabled(true);
}
void MainWindow::doProcessError(QAbstractSocket::SocketError err)
{
qDebug()<<err;
qDebug()<<myClient->errorString();
}
//发送数据
void MainWindow::on_btn_Send_clicked()
{
QString msg = ui->textEdit_2->toPlainText();
int ret = myClient->write(msg.toUtf8());
qDebug()<<ret;
if(ret <=0){
return;
}
ui->textEdit_2->clear();
}
END |
🎏文章原创,首发于CSDN论坛。
🎏欢迎点赞❤❤收藏⭐⭐打赏💴💴!
🎏欢迎评论区或私信指出错误❌,提出宝贵意见或疑问❓。
版权说明:如非注明,本站文章均为 扬州驻场服务-网络设备调试-监控维修-南京泽同信息科技有限公司 原创,转载请注明出处和附带本文链接。
请在这里放置你的在线分享代码