范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

正点原子I。MX6U嵌入式Qt开发指南第十一章网络编程3

  今日头条/西瓜视频/抖音短视频 同名:正点原子
  原子哥今日头条/西瓜视频/抖音短视频账号:正点原子原子哥
  感谢各位的关注和支持,你们的关注和支持是正点原子无限前进的动力。
  第十一章《网络编程》
  由于本章内容较多,所以第十一章《网络编程》将会分为几个部分进行内容的发布,更多文章内容请持续关注今日头条正点原子官方账号。11.3 UDP通信11.3.1 UDP简介
  UDP(User Datagram Protocol即用户数据报协议)是一个 轻量级的,不可靠的,面向数据报的无连接协议 。我们日常生活中使用的QQ,其聊天时的文字内容是使用UDP协议进行消息发送的。因为QQ有很多用户,发送的大部分都是短消息,要求能及时响应,并且对安全性要求不是很高的情况下使用UDP协议。但是QQ也并不是完全使用UDP协议,比如我们在传输文件时就会选择TCP协议,保证文件正确传输。像QQ语音和QQ视频通话,UDP的优势就很突出了。在选择使用协议的时候,选择UDP必须要谨慎。在网络质量令人十分不满意的环境下,UDP协议数据包丢失会比较严重。但是由于UDP的特性:它 不属于连接型协议 ,因而具有资源消耗小,处理速度快的优点,所以通常音频、视频和普通数据在传送时使用UDP较多,因为它们即使偶尔丢失一两个数据包,也不会对接收结果产生太大影响。
  QUdpSocket类提供了一个UDP套接字。QUdpSocket是QAbstractSocket的子类,允许发送和接收UDP数据报。使用该类最常见的方法是使用bind()绑定到一个地址和端口,然后调用writeDatagram()和readDatagram() / receiveDatagram()来传输数据。注意发送数据一般少于512字节。如果发送多于512字节的数据,即使我们发送成功了,也会在IP层被分片(分成小片段)。
  如果您想使用标准的QIODevice函数read()、readLine()、write()等,您必须首先通过调用connectToHost()将套接字直接连接到对等体。每次将数据报写入网络时,套接字都会发出bytesWritten()信号。
  如果您只是想发送数据报,您不需要调用bind()。readyRead()信号在数据报到达时发出。在这种情况下,hasPendingDatagrams()返回true。调用pendingDatagramSize()来获取第一个待处理数据报的大小,并调用readDatagram()或receiveDatagram()来读取它。注意:当您接收到readyRead()信号时,一个传入的数据报应该被读取,否则这个信号将不会被发送到下一个数据报。
  UDP通信示意图如下。重点是QUdpSocket类,已经为我们提供了UDP通信的基础。
  UDP消息传送有三种模式,分别是单播、广播和组播三种模式。
  单播(unicast):单播用于两个主机之间的端对端通信,需要知道对方的IP地址与端口。
  广播(broadcast):广播UDP与单播UDP的区别就是IP地址不同,广播一般使用广播地址255.255.255.255,将消息发送到在同一广播(也就是局域网内同一网段)网络上的每个主机。值得强调的是:本地广播信息是不会被路由器转发。当然这是十分容易理解的,因为如果路由器转发了广播信息,那么势必会引起网络瘫痪。这也是为什么IP协议的设计者故意没有定义互联网范围的广播机制。广播地址通常用于在网络游戏中处于同一本地网络的玩家之间交流状态信息等。其实广播顾名思义,就是想局域网内所有的人说话,但是广播还是要指明接收者的端口号的,因为不可能接受者的所有端口都来收听广播。
  组播(multicast):组播(多点广播),也称为"多播",将网络中同一业务类型主机进行了逻辑上的分组,进行数据收发的时候其数据仅仅在同一分组中进行,其他的主机没有加入此分组不能收发对应的数据。在广域网上广播的时候,其中的交换机和路由器只向需要获取数据的主机复制并转发数据。主机可以向路由器请求加入或退出某个组,网络中的路由器和交换机有选择地复制并传输数据,将数据仅仅传输给组内的主机。多播的这种功能,可以一次将数据发送到多个主机,又能保证不影响其他不需要(未加入组)的主机的其他通信。
  注意:单播一样和多播是允许在广域网即Internet上进行传输的,而广播仅仅在同一局域网上才能进行。 11.3.2 UDP单播与广播
  广播UDP与单播UDP的区别就是IP地址不同,所以我们的实例可以写成一个。我们可以这么理解,单播实际上是通信上对应一对一,广播则是一对多(多,这里指广播地址内的所有主机)。 11.3.2.1应用实例
  本例目的:了解QUdpSocket单播和广播使用。
  例10_udp_unicast_broadcast,UDP单播与广播应用(难度:一般)。项目路径为 Qt/2/10_udp_unicast_broadcast 。本例大体流程首先获取本地IP地址。创建一个udpSocket套接字,然后绑定本地主机的端口(也就是监听端口)。我们可以使用QUdpSocket类提供的读写函数readDatagram和writeDatagram,知道目标IP地址和端口,即可完成消息的接收与发送。
  项目文件10_udp_unicast_broadcast.pro文件第一行添加的代码部分如下。 10_udp_unicast_broadcast.pro编程后的代码  1   QT       += core gui network  2   3   greaterThan(QT_MAJOR_VERSION, 4): QT += widgets  4   5   CONFIG += c++11  6   7   # The following define makes your compiler emit warnings if you use  8   # any Qt feature that has been marked deprecated (the exact warnings  9   # depend on your compiler). Please consult the documentation of the  10  # deprecated API in order to know how to port your code away from it.  11  DEFINES += QT_DEPRECATED_WARNINGS  12  13  # You can also make your code fail to compile if it uses deprecated APIs.  14  # In order to do so, uncomment the following line.  15  # You can also select to disable deprecated APIs only up to a certain version of Qt.  16  #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0  17  18  SOURCES +=   19      main.cpp   20      mainwindow.cpp  21  22  HEADERS +=   23      mainwindow.h  24  25  # Default rules for deployment.  26  qnx: target.path = /tmp/${TARGET}/bin  27  else: unix:!android: target.path = /opt/${TARGET}/bin  28  !isEmpty(target.path): INSTALLS += target
  在头文件"mainwindow.h"具体代码如下。 mainwindow.h编程后的代码      /******************************************************************      Copyright   Deng Zhimao Co., Ltd. 1990-2021. All rights reserved.      * @projectName   10_udp_unicast_broadcast      * @brief         mainwindow.h      * @author        Deng Zhimao      * @email         1252699831@qq.com      * @net            www.openedv.com      * @date           2021-04-14      *******************************************************************/  1   #ifndef MAINWINDOW_H  2   #define MAINWINDOW_H  3   4   #include   5   #include   6   #include   7   #include   8   #include   9   #include   10  #include   11  #include   12  #include   13  #include   14  #include   15  #include   16  #include   17  18  class MainWindow : public QMainWindow  19  {  20      Q_OBJECT  21  22  public:  23      MainWindow(QWidget *parent = nullptr);  24      ~MainWindow();  25  26  private:  27      /* Udp通信套接字 */  28      QUdpSocket *udpSocket;  29  30      /* 按钮 */  31      QPushButton *pushButton[5];  32  33      /* 标签文本 */  34      QLabel *label[3];  35  36      /* 水平容器 */  37      QWidget *hWidget[3];  38  39      /* 水平布局 */  40      QHBoxLayout *hBoxLayout[3];  41  42      /* 垂直容器 */  43      QWidget *vWidget;  44  45      /* 垂直布局 */  46      QVBoxLayout *vBoxLayout;  47  48      /* 文本浏览框 */  49      QTextBrowser *textBrowser;  50  51      /* 用于显示本地ip */  52      QComboBox *comboBox;  53  54      /* 用于选择端口 */  55      QSpinBox  *spinBox[2];  56  57      /* 文本输入框 */  58      QLineEdit *lineEdit;  59  60      /* 存储本地的ip列表地址 */  61      QList IPlist;  62  63      /* 获取本地的所有ip */  64      void getLocalHostIP();  65  66  private slots:  67      /* 绑定端口 */  68      void bindPort();  69  70      /* 解绑端口 */  71      void unbindPort();  72  73      /* 清除文本框时的内容 */  74      void clearTextBrowser();  75  76      /* 接收到消息 */  77      void receiveMessages();  78  79      /* 发送消息 */  80      void sendMessages();  81  82      /* 广播消息 */  83      void sendBroadcastMessages();  84  85      /* 连接状态改变槽函数 */  86      void socketStateChange(QAbstractSocket::SocketState);  87  };  88  #endif // MAINWINDOW_H
  头文件里主要是声明界面用的元素,及一些槽函数。重点是声明udpSocket。
  在源文件"mainwindow.cpp"具体代码如下。 mainwindow.cpp编程后的代码      /******************************************************************      Copyright   Deng Zhimao Co., Ltd. 1990-2021. All rights reserved.      * @projectName   10_udp_unicast_broadcast      * @brief         mainwindow.cpp      * @author        Deng Zhimao      * @email         1252699831@qq.com      * @net            www.openedv.com      * @date           2021-04-14      *******************************************************************/  1   #include "mainwindow.h"  2    3   MainWindow::MainWindow(QWidget *parent)  4       : QMainWindow(parent)  5   {  6       /* 设置主窗体的位置与大小 */  7       this->setGeometry(0, 0, 800, 480);  8    9       /* udp套接字 */  10      udpSocket = new QUdpSocket(this);  11   12      /* 绑定端口按钮 */  13      pushButton[0] = new QPushButton();  14      /* 解绑端口按钮 */  15      pushButton[1] = new QPushButton();  16      /* 清空聊天文本按钮 */  17      pushButton[2] = new QPushButton();  18      /* 发送消息按钮 */  19      pushButton[3] = new QPushButton();  20      /* 广播消息按钮 */  21      pushButton[4] = new QPushButton();  22   23      /* 水平布局一 */  24      hBoxLayout[0] = new QHBoxLayout();  25      /* 水平布局二 */  26      hBoxLayout[1] = new QHBoxLayout();  27      /* 水平布局三 */  28      hBoxLayout[2] = new QHBoxLayout();  29      /* 水平布局四 */  30      hBoxLayout[3] = new QHBoxLayout();  31   32      /* 水平容器一 */  33      hWidget[0] =  new QWidget();  34      /* 水平容器二 */  35      hWidget[1] =  new QWidget();  36      /* 水平容器三 */  37      hWidget[2] =  new QWidget();  38   39   40      vWidget = new QWidget();  41      vBoxLayout = new QVBoxLayout();  42   43      /* 标签实例化 */  44      label[0] = new QLabel();  45      label[1] = new QLabel();  46      label[2] = new QLabel();  47   48      lineEdit = new QLineEdit();  49      comboBox = new QComboBox();  50      spinBox[0] = new QSpinBox();  51      spinBox[1] = new QSpinBox();  52      textBrowser = new QTextBrowser();  53   54      label[0]->setText("目标IP地址:");  55      label[1]->setText("目标端口:");  56      label[2]->setText("绑定端口:");  57   58      /* 设置标签根据文本文字大小自适应大小  */  59      label[0]->setSizePolicy(QSizePolicy::Fixed,  60                              QSizePolicy::Fixed);  61      label[1]->setSizePolicy(QSizePolicy::Fixed,  62                              QSizePolicy::Fixed);  63      label[2]->setSizePolicy(QSizePolicy::Fixed,  64                              QSizePolicy::Fixed);  65   66      /* 设置端口号的范围,注意不要与主机的已使用的端口号冲突 */  67      spinBox[0]->setRange(10000, 99999);  68      spinBox[1]->setRange(10000, 99999);  69   70      pushButton[0]->setText("绑定端口");  71      pushButton[1]->setText("解除绑定");  72      pushButton[2]->setText("清空文本");  73      pushButton[3]->setText("发送消息");  74      pushButton[4]->setText("广播消息");  75   76      /* 设置停止监听状态不可用 */  77      pushButton[1]->setEnabled(false);  78   79      /* 设置输入框默认的文本 */  80      lineEdit->setText("您好!");  81   82      /* 水平布局一添加内容 */  83      hBoxLayout[0]->addWidget(pushButton[0]);  84      hBoxLayout[0]->addWidget(pushButton[1]);  85      hBoxLayout[0]->addWidget(pushButton[2]);  86   87      /* 设置水平容器的布局为水平布局一 */  88      hWidget[0]->setLayout(hBoxLayout[0]);  89   90      hBoxLayout[1]->addWidget(label[0]);  91      hBoxLayout[1]->addWidget(comboBox);  92      hBoxLayout[1]->addWidget(label[1]);  93      hBoxLayout[1]->addWidget(spinBox[0]);  94      hBoxLayout[1]->addWidget(label[2]);  95      hBoxLayout[1]->addWidget(spinBox[1]);  96   97      /* 设置水平容器的布局为水平布局二 */  98      hWidget[1]->setLayout(hBoxLayout[1]);  99   100     /* 水平布局三添加内容 */  101     hBoxLayout[2]->addWidget(lineEdit);  102     hBoxLayout[2]->addWidget(pushButton[3]);  103     hBoxLayout[2]->addWidget(pushButton[4]);  104  105     /* 设置水平容器三的布局为水平布局一 */  106     hWidget[2]->setLayout(hBoxLayout[2]);  107  108     /* 垂直布局添加内容 */  109     vBoxLayout->addWidget(textBrowser);  110     vBoxLayout->addWidget(hWidget[1]);  111     vBoxLayout->addWidget(hWidget[0]);  112     vBoxLayout->addWidget(hWidget[2]);  113  114     /* 设置垂直容器的布局为垂直布局 */  115     vWidget->setLayout(vBoxLayout);  116  117     /* 居中显示 */  118     setCentralWidget(vWidget);  119  120     /* 获取本地ip */  121     getLocalHostIP();  122  123     /* 信号槽连接 */  124     connect(pushButton[0], SIGNAL(clicked()),  125             this, SLOT(bindPort()));  126     connect(pushButton[1], SIGNAL(clicked()),  127             this, SLOT(unbindPort()));  128     connect(pushButton[2], SIGNAL(clicked()),  129             this, SLOT(clearTextBrowser()));  130     connect(pushButton[3], SIGNAL(clicked()),  131             this, SLOT(sendMessages()));  132     connect(pushButton[4], SIGNAL(clicked()),  133             this, SLOT(sendBroadcastMessages()));  134     connect(udpSocket, SIGNAL(readyRead()),  135             this, SLOT(receiveMessages()));  136     connect(udpSocket,  137             SIGNAL(stateChanged(QAbstractSocket::SocketState)),  138             this,  139             SLOT(socketStateChange(QAbstractSocket::SocketState)));  140 }  141  142 MainWindow::~MainWindow()  143 {  144 }  145  146 void MainWindow::bindPort()  147 {  148     quint16 port = spinBox[0]->value();  149  150     /* 绑定端口需要在socket的状态为UnconnectedState */  151     if (udpSocket->state() != QAbstractSocket::UnconnectedState)  152         udpSocket->close();  153  154     if (udpSocket->bind(port)) {  155         textBrowser->append("已经成功绑定端口:"  156                             + QString::number(port));  157  158         /* 设置界面中的元素的可用状态 */  159         pushButton[0]->setEnabled(false);  160         pushButton[1]->setEnabled(true);  161         spinBox[1]->setEnabled(false);  162     }  163 }  164  165 void MainWindow::unbindPort()  166 {  167     /* 解绑,不再监听 */  168     udpSocket->abort();  169  170     /* 设置界面中的元素的可用状态 */  171     pushButton[0]->setEnabled(true);  172     pushButton[1]->setEnabled(false);  173     spinBox[1]->setEnabled(true);  174 }  175  176 /* 获取本地IP */  177 void MainWindow::getLocalHostIP()  178 {  179     // /* 获取主机的名称 */  180     // QString hostName = QHostInfo::localHostName();  181  182     // /* 主机的信息 */  183     // QHostInfo hostInfo = QHostInfo::fromName(hostName);  184  185     // /* ip列表,addresses返回ip地址列表,注意主机应能从路由器获取到  186     // * IP,否则可能返回空的列表(ubuntu用此方法只能获取到环回IP) */  187     // IPlist = hostInfo.addresses();  188     // qDebug()<addItem(ip.toString());  194     //    }  195  196     /* 获取所有的网络接口,  197      * QNetworkInterface类提供主机的IP地址和网络接口的列表 */  198     QList list  199             = QNetworkInterface::allInterfaces();  200  201     /* 遍历list */  202     foreach (QNetworkInterface interface, list) {  203  204         /* QNetworkAddressEntry类存储IP地址子网掩码和广播地址 */  205         QList entryList  206                 = interface.addressEntries();  207  208         /* 遍历entryList */  209         foreach (QNetworkAddressEntry entry, entryList) {  210             /* 过滤IPv6地址,只留下IPv4 */  211             if (entry.ip().protocol() ==  212                     QAbstractSocket::IPv4Protocol) {  213                 comboBox->addItem(entry.ip().toString());  214                 /* 添加到IP列表中 */  215                 IPlist<clear();  226 }  227  228 /* 客户端接收消息 */  229 void MainWindow::receiveMessages()  230 {  231     /* 局部变量,用于获取发送者的IP和端口 */  232     QHostAddress peerAddr;  233     quint16 peerPort;  234  235     /* 如果有数据已经准备好 */  236     while (udpSocket->hasPendingDatagrams()) {  237         /* udpSocket发送的数据报是QByteArray类型的字节数组 */  238         QByteArray datagram;  239  240         /* 重新定义数组的大小 */  241         datagram.resize(udpSocket->pendingDatagramSize());  242  243         /* 读取数据,并获取发送方的IP地址和端口 */  244         udpSocket->readDatagram(datagram.data(),  245                                 datagram.size(),  246                                 &peerAddr,  247                                 &peerPort);  248         /* 转为字符串 */  249         QString str = datagram.data();  250  251         /* 显示信息到文本浏览框窗口 */  252         textBrowser->append("接收来自"  253                             + peerAddr.toString()  254                             + ":"  255                             + QString::number(peerPort)  256                             + str);  257     }  258 }  259  260 /* 客户端发送消息 */  261 void MainWindow::sendMessages()  262 {  263     /* 文本浏览框显示发送的信息 */  264     textBrowser->append("发送:" + lineEdit->text());  265  266     /* 要发送的信息,转为QByteArray类型字节数组,数据一般少于512个字节 */  267     QByteArray data = lineEdit->text().toUtf8();  268  269     /* 要发送的目标Ip地址 */  270     QHostAddress peerAddr = IPlist[comboBox->currentIndex()];  271  272     /* 要发送的目标端口号 */  273     quint16 peerPort = spinBox[1]->value();  274  275     /* 发送消息 */  276     udpSocket->writeDatagram(data, peerAddr, peerPort);  277 }  278  279 void MainWindow::sendBroadcastMessages()  280 {  281     /* 文本浏览框显示发送的信息 */  282     textBrowser->append("发送:" + lineEdit->text());  283  284     /* 要发送的信息,转为QByteArray类型字节数组,数据一般少于512个字节 */  285     QByteArray data = lineEdit->text().toUtf8();  286  287     /* 广播地址,一般为255.255.255.255,  288      * 同一网段内监听目标端口的程序都会接收到消息 */  289     QHostAddress peerAddr = QHostAddress::Broadcast;  290  291     /* 要发送的目标端口号 */  292     quint16 peerPort = spinBox[1]->text().toInt();  293  294     /* 发送消息 */  295     udpSocket->writeDatagram(data, peerAddr, peerPort);  296 }  297 /* socket状态改变 */  298 void MainWindow::socketStateChange(QAbstractSocket::SocketState state)  299 {  300     switch (state) {  301     case QAbstractSocket::UnconnectedState:  302         textBrowser->append("scoket状态:UnconnectedState");  303         break;  304     case QAbstractSocket::ConnectedState:  305         textBrowser->append("scoket状态:ConnectedState");  306         break;  307     case QAbstractSocket::ConnectingState:  308         textBrowser->append("scoket状态:ConnectingState");  309         break;  310     case QAbstractSocket::HostLookupState:  311         textBrowser->append("scoket状态:HostLookupState");  312         break;  313     case QAbstractSocket::ClosingState:  314         textBrowser->append("scoket状态:ClosingState");  315         break;  316     case QAbstractSocket::ListeningState:  317         textBrowser->append("scoket状态:ListeningState");  318         break;  319     case QAbstractSocket::BoundState:  320         textBrowser->append("scoket状态:BoundState");  321         break;  322     default:  323         break;  324     }  325 }
  第146~163行,绑定端口。使用bind方法,即可绑定一个端口。注意我们绑定的端口不能和主机已经使用的端口冲突!
  第165~174行,解绑端口。使用abort方法即可解绑。
  第229~258行,接收消息,注意接收消息是QByteArray字节数组。读数组使用的是readDatagram方法,在readDatagram方法里可以获取对方的套接字IP地址与端口号。
  第261~277行,单播消息,需要知道目标IP与目标端口号。即可用writeDatagram方法发送消息。
  第279~296行,广播消息与单播消息不同的是将目标IP地址换成了广播地址,一般广播地址为255.255.255.255。 11.3.2.2程序运行效果
  本实例可以做即是发送者,也是接收者。如果在同一台主机同一个系统里运行两个本例程序。不能绑定同一个端口!否则会冲突!当您想测试在同一局域网内不同主机上运行此程序,那么绑定的端口号可以相同。
  本例设置目标IP地址为127.0.0.1,此IP地址是Ubuntu/Windows上的环回IP地址,可以用于无网络时测试。绑定端口号与目标端口号相同,也就是说,此程序正在监听端口号为10000的数据,此程序也向目标IP地址127.0.0.1的10000端口号发送数据,实际上此程序就完成了自发自收。
  当我们点击发送消息按钮时,文本消息窗口显示发送的数据"您好!",同时接收到由本地IP 127.0.0.1发出的数据"您好!"。其中ffff:是通信套接字的标识。呵呵!您可能会问为什么不是本主机的其它地址如(192.168.1.x)发出的呢?因为我们选择了目标的IP地址为127.0.0.1,那么要与此目标地址通信,必须使用相同网段的IP设备与之通信。注意不能用本地环回发送消息到其他主机上。因为本地环回IP只适用于本地主机上的IP通信。
  当我们点击广播消息按钮时,广播发送的目标IP地址变成了广播地址255.255.255.255。那么我们将收到从本地IP地址192.168.x.x的数据。如下图,收到了从192.168.1.129发送过来的数据。因为环回IP 127.0.0.1的广播地址为255.0.0.0,所以要与255.255.255.255的网段里的IP通信数据必须是由192.168.x.x上发出的。如果其他同一网段上的其他主机正在监听目标端口,那么它们将同时收到消息。这也验证了上一小节为什么会从127.0.0.1发送数据。
  本例不难,可能有点绕,大家多参考资料理解理解,知识点有点多,如果没有些通信基础的话,我们需要慢慢吃透。
  未完待续....

12月1日下午消息,今天开始爱奇艺进行一轮大规模裁员12月1日下午消息,新浪科技独家获悉,今天开始爱奇艺进行一轮大规模裁员,多位被裁员工独家透露,此次裁员是爱奇艺历史上规模最大的一轮裁员,部分部门几乎全员被裁,即使是诸如内容智能硬件携号转网,原手机卡的话费可能不好拿回来上个月,大船办理了携号转网,新手机卡到了,携号入网算是办完了,但是有一件事要到这个月办理,那就是转网前卡里的话费怎么处理。转网前大船曾经咨询过联通的客服,ta说转网后,下个月可以去张磊的投资理念张磊创立的高瓴资本是目前亚洲地区资产管理规模最大的投资基金之一,规模达到600亿美元,他本人也成为耶鲁大学历史上第一位华人校董。高瓴资本投出了腾讯京东美团点评滴滴蔚来汽车UberA蒋尚义离去,梁孟松辞职,中芯国际发声明朗了事情逐渐明朗!去年有记者问梁孟松,中芯的14nm可否在国际上一战,当时其回答的是还需要一段时间,但是在今年却传来,已经可以与行业相提并论。这样的进度可以说是巨大的,且之后中芯也传来注册英国公司做跨境电商的优势1。可入驻AMAZONEBAY等电商平台英国本土公司入驻跨境电商品牌,利于产品销售,更受当地消费者信赖。2。享受低税率销售额8。5万英镑以下不需要注册缴纳VAT,超过8。5万英镑销C程序中与内存有关的常见错误与内存有关的错误属于那种最令人惊恐的错误。在时间和空间上,经常在距离错误源一段距离之后才表现出来。将错误的数据写到错误的位置,你的程序可能在最终失败之前运行了一段时间。下面列举并分宠物云领养小程序专业搭建开发宠物云领养小程序专业搭建开发团队宠物云领养小程序开发,宠物云领养小程序专业开发,宠物云领养小程序专业搭建开发,宠物领养软件开发,宠物领养软件搭建开发,宠物云领养软件专业开发随着移动互联网不断发展,诸多APP软件出分销商城小程序开发及解决方案分销商城小程序的开发模式,顾名思义就是所有微信用户都能申请成为商城小程序的分销员,参与商城的推广与宣传同时在别人达成交易后还可以获得一定的奖励或者返券之类的实惠。很多商家之所以会选小米发烧失败,苹果再度登顶销量第一,中国厂商还有未来吗?国产手机一味的跟风华为的价格,却没有一家能跟的上华为的技术!!!华为被制裁后,这导致后面的大批国产机价格和质量严重不匹配,导致国人对国产手机越来越失望!!!58K的价格,2K左右的华为户外电源京东旗舰店开售预备购盼望着,盼望着,国货之光华为户外电源开售了有了这台移动小电站哪怕山高水远手机不怕电量低了饿了不吃压缩饼干了野地真能打王者了整个人都硬气起来了12月2日0000开售,限时直降200元早上早点铺中午快餐店晚上烧烤摊分时共享店铺的经营模式是否合规?央广网北京12月2日消息(总台央广记者韩雪莹)作为新兴经济模式,共享经济不知不觉完成了从无到有,从有到少不了的跃迁,共享单车共享充电宝已经融入人们日常生活的方方面面。而近期,分时共
iPhone13爆料汇总!到底香不香?昨天看到评论区有同学想看iPhone13系列的爆料汇总,看来随着时间推移,想买新机的小伙伴都沉不住气了呀正好最近关于iPhone13的新消息比较多,而且新机已经基本定型,不会再有大华为P50定档本月底发布最强的国产化旗舰机本周已经有一款疑似P50系列的华为神秘新机获得入网认证,资料显示和配备了最高66W的快充头,而且这大几率是一款原生鸿蒙OS的手机。不出意外的话该机将搭载此前传闻的骁龙8884G版,苹果iPhone13Pro系列手机壳偷跑ProProMax镜头差异更小IT之家7月8日消息苹果iPhone12系列拥有5。4英寸6。1英寸6。7英寸三个尺寸四款机型,从目前爆料来看iPhone13(或12s)系列也会是同样的尺寸,机身方面除部分机型的华为P50系列终于来了搭载骁龙888,影像也有新突破这段时间,手机圈不断有新品发布,但是华为官方依旧没有消息,就连本应该4月左右举办的P系列旗舰发布会也没有消息,虽然大家理解华为因为外界因素而导致新品推迟,但还是有些唏嘘。不过,目前一加6小米8刷入win11并运行PC游戏win11发布后,众多玩机高手将win11刷入一加6以及小米8等骁龙845手机上,并且还在树莓派上运行。虽然骁龙845跑win11可能只是玩家的折腾玩趣,但是根据UP主主极客湾的测老年版APP兴起智能时代正加速拥抱老年人来源人民日报海外版老年版APP兴起,适老化改造提速,老年人加快享受智能生活融入数字时代智能时代正加速拥抱老年人。6月10日,支付宝上线长辈模式,页面字体变大,应用项目精简。6月29全新丰田汉兰达上市!终于不用加价了?6月25日,广汽丰田全新一代汉兰达正式上市,新车基于丰田TNGAK平台打造,全系均采用2。5LTHS混动系统,共推出6款配置车型,售价区间为26。8834。88万元。此外,全新汉兰李彦宏百度智能汽车正在研发当中预计2023年和大家见面金融界网7月8日消息百度创始人李彦宏出席2021世界人工智能大会表示,人工智能作为一个国家战略,如今已经深入人心,但是过去几年,业界对于人工智能的讨论主要集中在助推经济转型的方向,14年做到世界第一,为什么是海信开创了属于中国的激光电视时代PC世界第一,中国企业用了28年冰箱世界第一,中国企业用了23年空调世界第一,中国企业用了15年激光电视世界第一,中国企业只用了14年。在全球显示产业发展史上,这是中国企业一次漂亮显卡何时能回归原价?RTX30Super或在明年发布芯研所移动版的RTX30Super有消息了,将在明年初登场,或许会在CES2022上发布。随着新产品的到来,显卡价格会趋于正常。显卡缺货的时期可能有不少人关注RTX30xxSupe华为matepad11优缺点说下华为matepad11的优缺点吧,首先说下我是线下实际上手体验过华为商城预定了,浅谈一下首先说下优点把,HarmonyOS加持,LCD120hz高刷屏,支持全局手写,磁吸二代手