当前位置: 首页 > news >正文

模板网站定制网站深汕特别合作区小漠镇

模板网站定制网站,深汕特别合作区小漠镇,上海网站域名注册,企业网站建设实训体会5.1 TCP 网络调试助手 5.1.1 项目概述 网络相关的一些基础概念 - 面试用 学习 QTcpServer 学习 QTcpClient 学习 TextEdit 特定位置输入文字颜色 学习网络通信相关知识点 复习巩固之前 UI 控件 程序运行如下图所示 5.1.2 开发流程 5.1.3 QTtcp 服务器的关键流程 工程… 5.1 TCP 网络调试助手 5.1.1 项目概述 网络相关的一些基础概念 - 面试用 学习 QTcpServer 学习 QTcpClient 学习 TextEdit 特定位置输入文字颜色 学习网络通信相关知识点 复习巩固之前 UI 控件 程序运行如下图所示 5.1.2 开发流程 5.1.3 QTtcp 服务器的关键流程 工程建立需要在 .pro 加入网络权限 创建一个基于 QTcpServer 的服务端涉及以下关键步骤 1. 创建并初始化 QTcpServer 实例 实例化 QTcpServer 。 调用 listen 方法在特定端口监听传入的连接。 2. 处理新连接 为 newConnection 信号连接一个槽函数。 在槽函数中使用 nextPendingConnection 获取 QTcpSocket 以与客户端通信。 3. 读取和发送数据 通过连接 QTcpSocket 的 readyRead 信号来读取来自客户端的数据。 使用 write 方法发送数据回客户端。 4. 关闭连接 在适当的时候关闭 QTcpSocket 。 示例代码可能如下 class MyServer : public QObject {         Q_OBJECT public :         MyServer () {                 QTcpServer * server new QTcpServer ( this );                 connect ( server , QTcpServer::newConnection , this , MyServer::onNewConnection );         server - listen ( QHostAddress::Any , 1234 ); } private slots :         void onNewConnection () {                 QTcpSocket * clientSocket server - nextPendingConnection ();                 connect ( clientSocket , QTcpSocket::readyRead , this , MyServer::onReadyRead ); } void onReadyRead () {         QTcpSocket * clientSocket qobject_cast QTcpSocket * ( sender ());         // 读取数据         QByteArray data clientSocket - readAll ();         // 处理数据         // ...         } }; 5.1.4 TCP 协议 以下内容自省阅读和消化主要在面试之前类似八股文问答实际编程我们不需要关系这么多 QTcpSocket 类底下的 API 已经做好所有的封装。 TCP 传输控制协议是一种广泛使用的网络通信协议设计用于在网络中的计算机之间可靠地传输数据。它是互联网协议套件的核心部分通常与IP 互联网协议一起使用合称为 TCP/IP 。以下是 TCP 协议的一些基本特点 1. 面向连接 在数据传输之前 TCP 需要在发送方和接收方之间建立一个连接。这包括三次握手过程确保两端都准备好进行数据传输。 2. 可靠传输 TCP 提供可靠的数据传输服务这意味着它保证数据包准确无误地到达目的地。如果发生数据丢失或错误TCP 会重新发送数据包。 3. 顺序控制 TCP 保证数据包的传输顺序。即使数据包在网络中的传输顺序被打乱接收方也能按照正确的顺序重组这些数据。 4. 流量控制 TCP 使用窗口机制来控制发送方的数据传输速率以防止网络过载。这有助于防止接收方被发送方发送的数据所淹没。 5. 拥塞控制 TCP 还包括拥塞控制机制用来检测并防止网络拥塞。当网络拥塞发生时 TCP 会减少其数据传输速率。 6. 数据分段 大块的数据在发送前会被分割成更小的段以便于传输。这些段会被独立发送并在接收端重新组装。 7. 确认和重传 接收方对成功接收的数据包发送确认 ACK 信号。如果发送方没有收到确认它会重传丢失的数据包。 8. 终止连接 数据传输完成后 TCP 连接需要被正常关闭这通常涉及到四次挥手过程。 TCP 适用于需要高可靠性的应用如网页浏览、文件传输、电子邮件等。然而由于它的这些特性 TCP 在处理速度上可能不如其他协议如 UDP 那么快速。 TCP 协议中的三次握手和四次挥手是建立和终止连接的重要过程。下面是它们的简要描述 三次握手建立连接 三次握手的主要目的是在两台设备之间建立一个可靠的连接。它包括以下步骤 1. SYN 客户端向服务器发送一个 SYN 同步序列编号报文来开始一个新的连接。此时客户端进入SYN-SENT 状态。 2. SYN-ACK 服务器接收到 SYN 报文后回复一个 SYN-ACK 同步和确认报文。此时服务器进入SYN-RECEIVED状态。 3. ACK 客户端接收到 SYN-ACK 后发送一个 ACK 确认报文作为回应并进入 ESTABLISHED 已建立状态。服务器在收到这个ACK 报文后也进入 ESTABLISHED 状态。这标志着连接已经建立。 四次挥手断开连接 四次挥手的目的是终止已经建立的连接。这个过程包括以下步骤 1. FIN 当通信的一方完成数据发送任务后它会发送一个 FIN 结束报文来关闭连接。发送完 FIN报文后该方进入FIN-WAIT-1 状态。 2. ACK 另一方接收到 FIN 报文后发送一个 ACK 报文作为回应并进入 CLOSE-WAIT 状态。发送 FIN报文的一方在收到ACK 后进入 FIN-WAIT-2 状态。 3. FIN 在等待一段时间并完成所有数据的发送后 CLOSE-WAIT 状态的一方也发送一个 FIN 报文来请求关闭连接。 4. ACK 最初发送 FIN 报文的一方在收到这个 FIN 报文后发送一个 ACK 报文作为最后的确认并进入TIME-WAIT状态。经过一段时间后确保对方接收到了最后的 ACK 报文该方最终关闭连接。 在这两个过程中三次握手主要确保双方都准备好进行通信而四次挥手则确保双方都已经完成通信并同意关闭连接。 5.1.5 Socket Socket 不是一个协议而是一种编程接口 API 或机制用于在网络中实现通信。 Socket 通常在应用层和传输层之间提供一个端点使得应用程序可以通过网络发送和接收数据。它支持多种协议主要是TCP 和 UDP 。 以下是 Socket 的一些基本特点 ·类型 有两种主要类型的 Sockets —— TCP Socket 面向连接可靠和 UDP Socket 无连接不可靠。 ·应用 在各种网络应用中广泛使用如网页服务器、聊天应用、在线游戏等。 ·编程语言支持 大多数现代编程语言如 Python, Java, C, 等都提供 Socket 编程的支持。 ·功能 提供了创建网络连接、监听传入的连接、发送和接收数据等功能。 ·QT: 在 QT 组件中 QTcpSocket 用来管理和实现 TCP Socket 通信 QUdpSocket 用来管理和实现 UDP Socket 通信 总之Socket 是实现网络通信的基础工具之一它抽象化了网络层的复杂性为开发者提供了一种相对简单的方式来建立和管理网络连接。 5.2 UI 设计 5.3 网络通信核心代码 QTcpServer 是 Qt 网络模块的一部分用于构建 TCP 服务器。它提供了一种机制来异步监听来自客户端的连接。一旦接受了一个连接服务器就可以与客户端进行数据交换。 5.3.1 创建 TCP 服务端的核心代码 主要步骤如下 1. 创建 QTcpServer 实例 启动服务器并开始监听指定端口。 2. 监听连接请求 调用 listen() 方法使服务器监听特定的 IP 地址和端口。 3. 接受连接 当客户端尝试连接时 QTcpServer 产生一个信号。你需要实现一个槽 slot 来响应这个信号并接受连接。 4. 处理客户端连接 每个连接的客户端都关联一个 QTcpSocket 对象用于数据交换。 示例代码 #include QTcpServer #include QTcpSocket #include QCoreApplication #include QDebug int main ( int argc , char * argv []) {         QCoreApplication a ( argc , argv );         QTcpServer server ;         // 监听端口         if ( ! server . listen ( QHostAddress::Any , 12345 )) {                 qDebug () Server could not start ;                 return - 1 ;         }         qDebug () Server started! ;         // 当有新连接时执行相应的操作         QObject::connect ( server , QTcpServer::newConnection , [ ]() {         QTcpSocket * client server . nextPendingConnection ();         QObject::connect ( client , QTcpSocket::readyRead , [ client ]() {                 QByteArray data client - readAll ();                 qDebug () Received data: data ;                 client - write ( Hello, client! );         });         QObject::connect ( client , QTcpSocket::disconnected , client , QTcpSocket::deleteLater );          return a . exec (); } 代码解释 1. 创建 QTcpServer 对象 在主函数中直接创建了一个 QTcpServer 对象。 2. 监听端口 使用 listen() 方法监听所有接口上的 12345 端口。 3. 处理新连接 通过连接 newConnection 信号当有新客户端连接时会调用相应的槽函数。 4. 读取数据 为每个连接的客户端创建 QTcpSocket 对象并连接 readyRead 信号以接收数据。 5. 发送数据 向客户端发送响应消息。 6. 客户端断开连接时的处理 使用 disconnected 信号确保客户端在断开连接时被适当地清理。 这个代码示例展示了如何使用 QTcpServer 创建一个基本的 TCP 服务器而无需通过继承来扩展类。这种方式通常更简单适用于不需要复杂处理的基本应用场景 5.4 TCP 服务端项目开发 核心代码 1.widget.cpp #include widget.h #include ui_widget.h #include QHostAddress #include QDebug #include QTcpSocket #include QNetworkInterface #include QMessageBox Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) { ui-setupUi(this); this-setLayout(ui-verticalLayout); //建立服务端 tcpSever new QTcpServer(this); connect(tcpSever,SIGNAL(newConnection()),this,SLOT(on_newClient_connect())); /* 服务端建立连接 */ /*鼠标左键刷新comboBox_children将客户端的端口号标在comboBox_children */ connect(ui-comboBox_children,MyComboBox::myComboBox_clicked,this,Widget::on_myComboBox_Refresh); //界面初始化 ui-btnStopListen-setEnabled(false); ui-btnBreak-setEnabled(false); //QListQHostAddress QNetworkInterface::allAddresses() QListQHostAddress addresss QNetworkInterface::allAddresses(); /* 获取所有地址信息 */ for(QHostAddress tmpAdd : addresss){ /* 遍历地址 */ if(tmpAdd.protocol() QAbstractSocket::IPv4Protocol){ /* 选择IPv4地址 */ ui-comboBox_Addr-addItem(tmpAdd.toString()); /* 将选择的IPv4地址传递到comboBox上 */ } } } Widget::~Widget() { delete ui; } /* 有客户端接入函数 */ void Widget::on_newClient_connect() { qDebug() newClient connect In; //当有客户端接入时接收到newconnection信号 if(tcpSever-hasPendingConnections()){ //QTcpSocket *QTcpServer::nextPendingConnection() QTcpSocket *connection tcpSever-nextPendingConnection(); /* 通过这个函数找到服务端的地址和端口号 */ //方便调试 qDebug() Client Addr: connection-peerAddress().toString() Client Port: connection-peerPort(); //打印在textEdit_Rev上显示 ui-textEdit_Rev-insertPlainText(\r\n服务端地址connection-peerAddress().toString() \r\n服务端端口QString::number(connection-peerPort())); //光标位置 ui-textEdit_Rev-moveCursor(QTextCursor::End); ui-textEdit_Rev-ensureCursorVisible(); //建立服务端接收客户端信息 connect(connection,SIGNAL(readyRead()),this,SLOT(on_readyRead_handler())); //检测客户端是否断开QAbstractSocket::disconnected() connect(connection,SIGNAL(disconnected()),this,SLOT(mdisConnect_Client())); } } /* 接收客户端信息处理函数 */ void Widget::on_readyRead_handler() { qDebug() revData ; //由于QTcpSocket *connection是局部变量无法接收到发送的信号 QTcpSocket * tmpSocket qobject_castQTcpSocket *(sender()); /* 接收发送信号函数 */ QByteArray revData tmpSocket-readAll(); /* readAll()该函数的返回值是QByteArray */ ui-textEdit_Rev-insertPlainText(\n客户端 revData); /* 将接收的数据打印在textEdit_Rev */ //光标位置 ui-textEdit_Rev-moveCursor(QTextCursor::End); ui-textEdit_Rev-ensureCursorVisible(); } /* 服务端检测客户端断开状态 */ void Widget::mdisConnect_Client() { //由于QTcpSocket *connection是局部变量无法接收到发送的信号 QTcpSocket * tmpSocket qobject_castQTcpSocket *(sender()); tmpSocket-deleteLater(); /* 清除tcpSever-findChildren遗留下的端口号0 */ ui-textEdit_Rev-insertPlainText(\n客户端断开!); //光标位置 ui-textEdit_Rev-moveCursor(QTextCursor::End); ui-textEdit_Rev-ensureCursorVisible(); } void Widget::on_btnStartListen_clicked() { //bool QTcpServer::listen(const QHostAddress address QHostAddress::Any, quint16 port 0) //QHostAddress(const QString address) //QHostAddress addr(192.168.43.83); int port ui-lineEdit-text().toUInt(); /* 手动输入端口号 */ //if(!tcpSever-listen(QHostAddress::Any,port)){ if(!tcpSever-listen(QHostAddress(ui-comboBox_Addr-currentText()),port)){ /* 如果没有监听到有客户端接入跳出该函数 有的话就将客户端和客户端端口号发送给tcpSever的信号 响应槽函数on_newClient_connect*/ qDebug() Listen Error; QMessageBox msgBox; msgBox.setWindowTitle(监听失败); msgBox.setText(端口号被占用); msgBox.exec(); return; } //按键界面优化 ui-btnStartListen-setEnabled(false); ui-btnStopListen-setEnabled(true); ui-btnBreak-setEnabled(true); } /* 服务端发送按键 */ void Widget::on_btn_Send_clicked() { //找到对应的客户端来接收QListT QObject::findChildren(const QString name QString() QListQTcpSocket * tmpSocketClients tcpSever-findChildrenQTcpSocket *(); //当用户不选择all向特定的客户端进行发送 if(ui-comboBox_children-currentText() ! all){ //根据用户选择客户端通过ChildrenINdex来查找该变量在用户选中条目后触发的on_comboBox_children_activated()区赋值 tmpSocketClients[ChildrenINdex]-write(ui-textEdit_Send-toPlainText().toStdString().c_str()); } else{ //遍历所有客户端并一一调用write含糊向客户端发送信息 for(QTcpSocket *tmpSocket : tmpSocketClients){ tmpSocket-write( ui-textEdit_Send-toPlainText().toStdString().c_str()); /* write(const char *data)将QString转为const char* */ } } } /* 服务端可选择特定客户端发送信息 */ void Widget::on_myComboBox_Refresh() { ui-comboBox_children-clear(); QListQTcpSocket * tmpSocketClients tcpSever-findChildrenQTcpSocket *(); //遍历所有客户端 for(QTcpSocket *tmpSocket : tmpSocketClients){ if(tmpSocket ! nullptr) /* 没有空指针 */ if(tmpSocket-peerPort() ! 0) /* 端口号不为0 */ ui-comboBox_children-addItem(QString::number( tmpSocket-peerPort())); } ui-comboBox_children-addItem(all); } /* 表示tmpSocketClients的下标 */ void Widget::on_comboBox_children_activated(int index) { ChildrenINdex index; } /* 停止监听 */ void Widget::on_btnStopListen_clicked() { QListQTcpSocket * tmpSocketClients tcpSever-findChildrenQTcpSocket *(); //遍历所有客户端 for(QTcpSocket *tmpSocket : tmpSocketClients){ tmpSocket-close(); } tcpSever-close(); ui-btnStartListen-setEnabled(true); ui-btnStopListen-setEnabled(false); ui-btnBreak-setEnabled(false); } /* 断开 */ void Widget::on_btnBreak_clicked() { on_btnStopListen_clicked(); delete tcpSever; this-close(); } 2.widget.h #ifndef WIDGET_H #define WIDGET_H #include QWidget #include QTcpServer #include mycombobox.h QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACE class Widget : public QWidget { Q_OBJECT public: Widget(QWidget *parent nullptr); ~Widget(); QTcpServer *tcpSever; public slots: /* 有客户端接入函数 */ void on_newClient_connect(); /* 接收客户端信息处理函数 */ void on_readyRead_handler(); /* 服务端检测客户端断开状态 */ void mdisConnect_Client(); void on_myComboBox_Refresh(); private slots: /* 监听函数 */ void on_btnStartListen_clicked(); /* 服务端发送按键 */ void on_btn_Send_clicked(); void on_comboBox_children_activated(int index); void on_btnStopListen_clicked(); void on_btnBreak_clicked(); private: Ui::Widget *ui; int ChildrenINdex 0; }; #endif // WIDGET_H 3.MyComboBox.cpp #include mycombobox.h #include QMouseEvent MyComboBox::MyComboBox(QWidget *parent) : QComboBox(parent) { } void MyComboBox::mousePressEvent(QMouseEvent *e) { if(e-button() Qt::LeftButton){ emit myComboBox_clicked(); } QComboBox::mousePressEvent(e); } 4.MyComboBox.h #ifndef MYCOMBOBOX_H #define MYCOMBOBOX_H #include QComboBox #include QWidget class MyComboBox : public QComboBox { Q_OBJECT public: MyComboBox(QWidget *parent); protected: void mousePressEvent(QMouseEvent *e) override; signals: void myComboBox_clicked(); }; #endif // MYCOMBOBOX_H 5.main.cpp #include widget.h #include QApplication int main(int argc, char *argv[]) { QApplication a(argc, argv); Widget w; w.show(); return a.exec(); }
http://www.w-s-a.com/news/642757/

相关文章:

  • 烟台网站建设优化网页设计师证
  • 手机微网站建设多少钱个人网站 wordpress
  • 做外贸是不是必须有网站wordpress网络图片
  • 赣县企业网站建设用dw做网站的基本步骤
  • 辽源网站建设微信小程序公众平台
  • 多媒体网站设计开发是指什么常宁网站建设
  • 淄博网站推广优化17岁在线观看免费高清完整版
  • 企业形象网站开发业务范畴wordpress最好最全的教程
  • 企业网站的建立意义网站首页制作网站
  • 网站制作过程内容深圳最好的活动策划公司
  • 深圳网站关键词排名查询公司网站怎么做啊
  • 微网站 制作平台广州电商聚集地
  • 建设外国商城网站网站服务器 虚拟主机
  • 天河网站建设开发电子商务公司名字大全
  • 站长推荐为何用wdcp建立网站连不上ftp
  • 云南旅行社网站开发学编程多久可以写游戏辅助
  • 推广网站的步骤网站备案号中信息有变
  • 优秀企业建站织梦能不能做门户网站
  • 广东省建设局官方网站wordpress 自动安装 插件怎么用
  • 哪类小网站容易做h5页面制作代码
  • 北京网站建设公司华网百度热搜seo
  • 小清新博客网站中山做网站公司
  • 美团做团购网站如何新建自己的网站
  • 安卓软件制作网站电子商务网站建设实训总结报告
  • 肃宁网站制作价格外国设计师素材网站
  • 自已建网站用jsp做的可运行的网站
  • 外贸建站代理网站建设设计公司哪家好
  • 普升高端品牌网站建设台州中兴建设咨询有限公司网站
  • 模板演示网站移动网站开发公司
  • 网站管理办法制度公司招聘信息