QTcpServer编程相关

本文介绍了QTcpServer编程,涉及TCP和UDP套接字的基础知识。在TCP/IP网络中,Qt的网络编程主要基于异步模式。示例展示了如何使用QTcpServer和QUdpSocket进行数据传输,包括TCP的流式协议特点和UDP的无连接、不可靠特性。文中通过一个客户端-服务器的文件传输示例,详细解释了TCP协议的使用,包括文件头结构的构建和数据发送过程。
摘要由CSDN通过智能技术生成

QTcpServer编程

网络编程,OSI(开放式系统互联参考模型)七层参考模型:应用层、表示层、会话层、传输层、网络层、数据链路层、物理层。

套接字(Socket)是网络通信的基本构建模块,又分为流式套接字(Stream Socket)和数据报套接字(Datagram Socket)两种类型的套接字。

TCP:传送控制协议(Transmission Control Protocol),这是一种提供给用户的可靠的全双工字节流面向连接的协议。

UDP:用户数据报协议(User Datagram Protocol),这是提供给用户进程的无连接协议,用于传送数据而不执行正确性检查。

当然TCP、UDP都归属于传输层协议。

对所用的网络知识简短的介绍,下面步入正题,开始Qt套接字编程~

在TCP/IP网络中两个进程间的相互作用的主要模式是客户机/服务器模式(Client/Server model),是构造分布式应用程序最常用的模式。

Qt中几乎所有的QtNetwork类都是异步的,一般情况下没有必要Socket使用在多线程中。

■、UDP
UDP是不可信赖的,它是基于包的协议。一些应用程序层的协议使用UDP是因为它比TCP更加小巧,数据是从一个主机到另一个主机以包的形式发送的。这里没有连接到的概念,并且如果一个UDP包没有被正确交付,它不会向系统报告任何错误。

下面写一个简单的广播示例,由客户端和服务器两部分组成。

   //客户端发送数据


   void Client::sendDatagram()


   {


       QByteArray datagram;


       QDataStream out(&datagram, QIODevice::WriteOnly);


       out.setVersion(QDataStream::Qt_4_3);


       out << QDateTime::currentDateTime() << "vic.MINg!" << 3.14;



       QUdpSocket udpSocket(this);


       udpSocket.writeDatagram(datagram, QHostAddress::Broadcast, 1981);


   }

在QByteArray型局部变量datagram中构建待发送的数据包,然后通过QUdpSocket类的 writeDatagram ( const QByteArray & datagram, const QHostAddress & host, quint16 port );函数将数据包发出。值得注意的是,这里的地址使用了QHostAddress::Broadcast值,它对应IPv4下的广播地址,如果将该值更换 成单机地址(如本机地址QHostAddress::LocalHost),将变成一个普通的点对点的UDP程序。

   //服务器接收数据


   void Server::initSocket()


   {


       udpSocket = new QUdpSocket(this);


       udpSocket->bind(1981);



       connect(udpSocket, SIGNAL(readyRead()),


               this, SLOT(readPendingDatagrams()));


   }

初始化生成QUdpSocket实例,并绑定与客户端约定的端口(1981)。这里多说几句,在编写网络程序时应该使用1024以上的端口号,1024以 下的端口号通常被系统保留,紧密的绑定了一些服务(如80端口是http服务、21端口是ftp服务)。

   void Server::readPendingDatagrams()


   {


       while (udpSocket->hasPendingDatagrams()) {


           QByteArray datagram;


           datagram.resize(udpSocket->pendingDatagramSize());


           QHostAddress sender;


           quint16 senderPort;



           udpSocket->readDatagram(datagram.data(), datagram.size(),


                                    &sender, &senderPort);


           QDateTime dateTime;


           QString name;


           double data;


           QDataStream in(&datagram, QIODevice::ReadOnly);


           in.setVersion(QDataStream::Qt_4_3);


           in >> dateTime >> name >> data;


       }


   }

接受数据函数首先调用QUdpSocket类的成员函数hasPendingDatagrams()以判断是否有可供读取的数据。如果有则通过 pendingDatagramSize()获取当前可供读取的UDP报文大小,并据此大小分配接收缓冲区,

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值