QT5网络与通信
在应用程序开发中网络编程非常重要,目前互联网通行的TCP/IP协议,自上 而下分为应用层、传输层、网际层和网络接口层这四层。实际编写网络应用程序时 只使用到传输层和应用层,所涉及的协议主要包括UDP、TCP、FTP和HTTP等。
虽然目前主流的操作系统(Windows、Linux等)都提供了统一的套接字(Socket) 抽象编程接口(API),用于编写不同层次的网络程序,但是这种方式比较烦琐,甚 至有时需要引用底层操作系统的相关数据结构,而Qt提供的网络模块QtNetwork, 圆满地解决了这一问题。
获取本机网络信息
网络应用中,经常需要获得本机的主机名、IP地址和硬件地址等网络信息。运 用 可获得本机的网络信息。
其中:
• QString localHostName = QHostInfo::localHostName():获得本机主机名。 QHostlnfo提供了一系列有关网络信息的静态函数,可以根据主机名获得分配的IP 地址,也可以根据IP地址获得相应的主机名。
• QHostlnfo hostinfo = QHostlnfo::fromName(localHostName):根据主机名 获得相关主机信息,包括IP地址等。QHostlnfo::fromName()函数通过主机名查找 IP地址信息。
• QList listAddress = hostlnfo.addresses():获得主机的 IP 地 址列表。
• if(!listAddress.isEmpty()){…):获得的主机IP地址列表可能为空。在不为空 的情况下使用第一个IP地址。
#include <QApplication> #include <iostream> #include <QHostAddress> #include <QNetworkInterface> #include <QHostInfo> #include <QMessageBox> int main(int argc, char *argv[]) { QApplication a(argc, argv); QString localHostName = QHostInfo::localHostName(); QHostInfo hostinfo = QHostInfo::fromName(localHostName); QList<QHostAddress> listAddress = hostinfo.addresses(); if(!listAddress.isEmpty()) { std::cout << listAddress.first().toString().toStdString() << std::endl; } QString detail=""; QList<QNetworkInterface> list = QNetworkInterface::allInterfaces(); for(int i = 0 ; i < list.count() ; i++) { QNetworkInterface interfaces = list.at(i); detail=detail+("设备:")+interfaces.name()+"\n"; detail=detail+("硬件地址:")+interfaces.hardwareAddress () +"\n"; QList<QNetworkAddressEntry> entryList=interfaces.addressEntries(); for(int j = 0;j<entryList.count();j++) { QNetworkAddressEntry entry=entryList.at(j); detail=detail+"\t"+("IP 地址:") +entry.ip().toString() +"\n"; detail=detail+"\t"+("子网掩码:") +entry.netmask().toString ()+"\n"; detail=detail+"\t"+ ("广播地址:") +entry.broadcast().toString ()+"\n"; } } QMessageBox::information(0, ("Detail1") , detail); return a.exec (); }
基于UDP的网络广播程序
传输层另一个重要的协议就是用户数据报协议 UDP。UDP 只在 IP 的数据报服务之上增加了很少一点的功能,这就是复用和分用的功能以及差错检测的功能。
UDP的主要特点是:
(1)UDP 是无连接的。即发送数据之前不需要建立连接(当然,发送数据结束时也没有连接可释放),因此减少了开销和发送数据之前的时延。
(2)UDP 使用尽最大努力交付。即不保证可靠交付,因此主机不需要维护复杂的连接状态表(这里面有许多参数)。
(3)UDP 是面向报文的。发送方的 UDP 对应用程序交下来的报文,在添加首部后就向下交付 IP 层。UDP 对应用层交下来的报文,既不合并,也不分拆,而是保留这些报文的边界。这就是说,应用层交给 UDP 多长的报文,UDP 就照样发送,即一次发送一个报文,如图 5-4 所示。在接收方的 UDP,对 IP 层交上来的 UDP 用户数据报,在去除首部后就原封不动地交付上层的应用进程。也就是说,UDP 一次交付一个完整的报文。因此,应用程序必须选择合适大小的报文。若报文太长,UDP 把它交给 IP 层后,IP 层在传送时可能要进行分片处理,这会降低 IP 层的效率。反之,若报文太短,UDP 把它交给 IP 层后,会使 IP 数据报的首部的相对长度太大,这也降低了 IP 层的效率。
(4)UDP 没有拥塞控制。因此网络出现的拥塞不会使源主机的发送速率降低。这对某些实时应用是很重要的。很多的实时应用(如:IP电话、实时视频会议等)要求源主机以恒定的速率发送数据,并且允许在网络出现拥塞时丢失一部分数据,但却不允许数据有太大的时延。UDP 协议正好适合这种要求。
(5)UDP 支持一对一、一对多、多对一和多对多的交互通信。
(6)UDP的首部开销小,只有 8 个字节,比 TCP 的 20 个字节的首部要短。
用户数据报 UDP 有两个部分组成:首部 + 数据部分。首部部分很简单,只有 8 个字节(如图 5-5),由四个字段组成,每个字段的长度都是两个字节。各字段含义如下:
(1)源端口:源端口号。在需要对方回信时选用。不需要使用时可用 0 填充。
(2)目的端口:目的端口号。这在终点交付报文时必须使用。
(3)长度:UDP 用户数据报的长度,其最小值是 8(即仅有首部部分),单位:字节。
(4)校验和:检测 UDP 用户数据报在传输过程中是否出错。有错就丢弃。
相关文章网络上一大堆,请自己搜索查看
基于TCP的网络聊天室程序
TCP(Transmission Control Protocol)传输控制协议,是一种面向连接的、可靠的、基于字节流的传输层协议。人如其名,通俗地说TCP就是对于传输、发送、通信进行控制的协议。
开始介绍TCP之前我们先来介绍一下连接,连接是指各种设备、线路,或者是网络中进行通信的两个应用程序为了互相传递消息而专有的、虚拟的通信线路,因此也可以把连接叫做虚拟电路。一旦连接成功建立,那么需要进行通信的应用程序只需要使用这条虚拟的通信线路发送并接收数据即可,应用程序并不需要担心这条线路是如何建立、断开以及保持的管理工作,这些都是TCP来进行控制的。
TCP的特点
为了通过IP数据报实现可靠性传输,就必须要考虑到在传输过程中,数据被破坏、丢包、重复以及数据包到达时的顺序混乱的问题,如果解决不了这些问题,那么无法保证传输的可靠性了,TCP通过检验和,序列号、确认应答、重发控制、连接管理以及窗口控制等机制实现了可靠性传输。
相关文章网络上一大堆,请自己搜索查看
QT网络应用开发初步
QNetworkAceessManager的使用。
重要: 上述部分会在QT日常中更新相关代码,请关注日常专栏