Qt网络编程
2015-05-31 23:00
429 查看
Qt网络编程
sf2gis@163.com
2015年5月2日
方法:HTTP,FTP,TCP,UDP
使用QtNetwork框架的相关类操作。
请求:QNetworkRequest。
回复:QNetworkReply。
操作管理:QNetworkAccessManager。负责进行HTTP操作及状态。
进度:QNetworkReply发送downloadProgress()信号。
{
QNetworkAccessManager *pManager = newQNetworkAccessManager(this);
connect(pManager,SIGNAL(finished(QNetworkReply*)),this,SLOT(handleReply(QNetworkReply*)));
QNetworkReply *reply =pManager->get(QNetworkRequest(QUrl("http://www.gfsoso.net/")));
connect(reply,SIGNAL(downloadProgress(qint64,qint64)),this,SLOT(handleProgress(qint64,qint64)));
}
voidMainWindow::handleReply(QNetworkReply *reply)
{
QString strReply(reply->readAll());
qDebug()<<strReply;
ui->textBrowser->setText(strReply);
reply->deleteLater();
}
voidMainWindow::handleProgress(qint64 readBytes,qint64 totalBytes)
{
ui->progressBar->setMaximum(totalBytes);
ui->progressBar->setValue(readBytes);
}
{
QByteArray ba = reply->readAll();
QString strReply(ba);
qDebug()<<strReply;
ui->textBrowser->setText(strReply);
QFile file("test.tar.gz");
file.open(QFile::WriteOnly);
file.write(ba);
file.close();
reply->deleteLater();
}
voidMainWindow::handleProgress(qint64 readBytes,qint64 totalBytes)
{
ui->progressBar->setMaximum(totalBytes);
ui->progressBar->setValue(readBytes);
}
voidMainWindow::ftp()
{
QNetworkAccessManager *pManager = newQNetworkAccessManager(this);
connect(pManager,SIGNAL(finished(QNetworkReply*)),this,SLOT(handleReply(QNetworkReply*)));
QNetworkReply *reply =pManager->get(QNetworkRequest(QUrl("ftp://ftp.pku.edu.cn/open/db/MySQL/mysql-connector-java-5.1.21.tar.gz")));
connect(reply,SIGNAL(downloadProgress(qint64,qint64)),this,SLOT(handleProgress(qint64,qint64)));
}
GET与POST的区别:get使用url的一部分传递参数,可见,长度有限(2048),只能传递ascii。post使用单独传递数据,不可见,长度不了,可传递二进制数据。
参考:http://www.w3school.com.cn/tags/html_ref_httpmethods.asp
http://zh.wikipedia.org/zh/%E8%B6%85%E6%96%87%E6%9C%AC%E4%BC%A0%E8%BE%93%E5%8D%8F%E8%AE%AE
REST和SOAP:目标简单的进行web service。REST使用HTTP方式CRUD,无状态,简单,安全性差,将所有对象抽象为资源,以URL进行请求。SOAP只使用POST,有状态,使用复杂,安全性好,将所有数据封装为XML进行交互。
参考:http://www.cnblogs.com/zhangz721/archive/2009/10/02/1577316.html
示例:参见Http请求页面
方法:使用20端口传输文件,21端口传输命令。
参考:
http://zh.wikipedia.org/zh/%E6%96%87%E4%BB%B6%E4%BC%A0%E8%BE%93%E5%8D%8F%E8%AE%AE
示例:参见FTP下载文件
参考:
http://blog.csdn.net/fuyoufang1/article/details/18215081
原理:IP:internet protocol,互联网协议,为不同的主机分配唯一的ip地址。DNS(Domain NameService)将不同Url中名称解析为ip地址。IP地址有IPV4和IPV6两种。
子网掩码:区分不同局域网网段的掩码,过滤相同部分,以确定所属的网段。
网关:外部网络出口。局域网网络向外部发送数据时,会发送到网关,再由网关转发到目的网络。
参考:http://www.hackbase.com/tech/2015-01-12/70390.html
http://zh.wikipedia.org/wiki/%E7%BD%91%E5%85%B3
获取IP地址的域名:QHostInfo::lookupHost(“IP地址”)。
示例:
void MainWindow::hostInfo()
{
qDebug()<<QHostInfo::localDomainName()<<","<<QHostInfo::localHostName();
qDebug()<<QHostInfo::fromName("www.baidu.com").addresses();
QHostInfo::lookupHost("www.baidu.com",this,SLOT(handleHost(QHostInfo)));
}
voidMainWindow::handleHost(const QHostInfo &hostInfo)
{
foreach(const QHostAddress&addr,hostInfo.addresses())
{
qDebug()<<addr.toString();
}
}
IP信息:QNetworkAddressEntry,每一个IP地址及其子网掩码和网关信息。
参考:http://blog.klniu.com/post/qnetworkinterface-class/
示例:
void MainWindow::interfaces()
{
qDebug()<<QNetworkInterface::allAddresses();
foreach(const QNetworkInterface&interface,QNetworkInterface::allInterfaces())
{
qDebug()<<"interface:"<<interface.name()<<interface.hardwareAddress();
foreach(const QNetworkAddressEntry&entry,interface.addressEntries())
{
qDebug()<<"Entry:"<<entry.ip()<<entry.netmask()<<entry.broadcast();
}
}
}
结果
(QHostAddress("fe80::2507:109f:3858:d133%15"), QHostAddress( "169.254.209.51" ) , QHostAddress( "192.168.22.1") , QHostAddress( "fe80::4cc6:bb45:659f:58a9%12" ) , QHostAddress("169.254.88.169" ) , QHostAddress( "192.168.1.102" ) ,QHostAddress( "fe80::254b:6d06:925:b6f5%20"
) , QHostAddress("192.168.206.1" ) , QHostAddress("fe80::8c8a:179b:ecb0:a9d3%22" ) , QHostAddress("192.168.217.1" ) , QHostAddress( "::1" ) , QHostAddress("127.0.0.1" ) , QHostAddress( "fe80::5efe:c0a8:d901%18" ) ,QHostAddress( "2001:0:9d38:6ab8:188f:ad3d:8a8d:71e3"
) , QHostAddress("fe80::188f:ad3d:8a8d:71e3%17" ) , QHostAddress( "fe80::5efe:c0a8:166%23") )
interface:"{6059E8E0-FCF5-4B12-9C6D-EC97B540E1AD}""44:6D:57:5E:95:73"
Entry: QHostAddress("fe80::2507:109f:3858:d133%15" ) QHostAddress("ffff:ffff:ffff:ffff::" ) QHostAddress( "" )
Entry: QHostAddress("169.254.209.51" ) QHostAddress( "" ) QHostAddress("" )
Entry: QHostAddress("192.168.22.1" ) QHostAddress( "" ) QHostAddress("" )
interface:"{253576A5-E502-4A9C-9394-88D45EE4B107}""00:21:CC:C8:A1:CF"
Entry: QHostAddress("fe80::4cc6:bb45:659f:58a9%12" ) QHostAddress( "ffff:ffff:ffff:ffff::") QHostAddress( "" )
Entry: QHostAddress("169.254.88.169" ) QHostAddress( "" ) QHostAddress("" )
interface:"{33AC696B-F917-423B-A17B-88AFFA264C4C}""44:6D:57:5E:95:73"
Entry: QHostAddress("192.168.1.102" ) QHostAddress( "255.255.255.0" )QHostAddress( "192.168.1.255" )
interface:"{A1696BDD-A453-4D81-9AFC-A22A7553EAAD}""00:50:56:C0:00:01"
Entry: QHostAddress("fe80::254b:6d06:925:b6f5%20" ) QHostAddress("ffff:ffff:ffff:ffff::" ) QHostAddress( "" )
Entry: QHostAddress("192.168.206.1" ) QHostAddress( "255.255.255.0" )QHostAddress( "192.168.206.255" )
interface:"{5F04202D-B1C9-4CD3-951F-F1FD4C091D2E}""00:50:56:C0:00:08"
Entry: QHostAddress("fe80::8c8a:179b:ecb0:a9d3%22" ) QHostAddress("ffff:ffff:ffff:ffff::" ) QHostAddress( "" )
Entry: QHostAddress("192.168.217.1" ) QHostAddress( "255.255.255.0" )QHostAddress( "192.168.217.255" )
interface:"{846EE342-7039-11DE-9D20-806E6F6E6963}" ""
Entry: QHostAddress("::1" ) QHostAddress("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" ) QHostAddress("" )
Entry: QHostAddress("127.0.0.1" ) QHostAddress( "" ) QHostAddress( "")
interface:"{E021EE1B-15F5-425A-92CE-685790FE0031}" "00:00:00:00:00:00:00:E0"
interface:"{31FDE048-BFF0-4DB6-9D80-4362D1CAE28F}""00:00:00:00:00:00:00:E0"
Entry: QHostAddress("fe80::5efe:c0a8:d901%18" ) QHostAddress("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" ) QHostAddress("" )
interface:"{C534E5AC-9EA2-4E25-8017-8F5628B7338D}""00:00:00:00:00:00:00:E0"
Entry: QHostAddress("2001:0:9d38:6ab8:188f:ad3d:8a8d:71e3" ) QHostAddress( "::") QHostAddress( "" )
Entry: QHostAddress("fe80::188f:ad3d:8a8d:71e3%17" ) QHostAddress("ffff:ffff::" ) QHostAddress( "" )
interface: "{E858920C-9CEA-4C35-9F85-9609D71CA21D}""00:00:00:00:00:00:00:E0"
interface:"{3B61355E-6D8F-441F-9379-020F9551733B}""00:00:00:00:00:00:00:E0"
interface:"{7E8F026C-AA3B-4F39-AA8E-5726B3382763}""00:00:00:00:00:00:00:E0"
interface:"{3D3A432C-5A7E-4E00-BA86-EE4309C419EF}""00:00:00:00:00:00:00:E0"
Entry: QHostAddress("fe80::5efe:c0a8:166%23" ) QHostAddress("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" ) QHostAddress("" )
原理:发送方设置数据及其相关信息(发送方地址:端口,目标地址:端口,长度,校验,数据等)打包发送,不再处理其它问题。
端口:目标是区分指同一协议下的不同连接。0~65535,1024之下系统保留,应尽量使用大的端口号。
参考:http://www.nwnu.edu.cn/Article.do_id=301.html
方法:UDP,短小快速,数据量应该尽量少,一般不要超过512B。
监听指定IP:Port:bind()。只有服务端需要绑定端口以固定收发地址,客户端动态绑定。
发送数据:writeDatagram直接发送,动态绑定端口。
接收数据:事件驱动,发送readyRead()消息。hasPendingDatagram()检测是否有数据,readDatagram()读取数据。
示例:
发送方:ip=192.168.1.102
void MainWindow::udpSender()
{
QUdpSocket *pSender = new QUdpSocket(this);
QByteArray ba("againxx");
pSender->writeDatagram(ba,QHostAddress("192.168.217.129"),12306);
}
接收方:ip=192.168.217.129
void MainWindow::receive()
{
QUdpSocket *pUdp = new QUdpSocket(this);
pUdp->bind(12306,QAbstractSocket::ShareAddress);
connect(pUdp,SIGNAL(readyRead()),this,SLOT(handleUdpData()));
m_pUdp = pUdp;
}
voidMainWindow::handleUdpData()
{
while(m_pUdp->hasPendingDatagrams())
{
int iSize=m_pUdp->pendingDatagramSize();
QByteArray baDatagram;
baDatagram.resize(iSize);
QHostAddress host;
quint16 port;
m_pUdp->readDatagram(baDatagram.data(),iSize,&host,&port);
qDebug()<<"receive-"<<host.toString()<<":"<<port<<"="<<baDatagram;
}
}
原理:底层协议,HTTP,FTP等都是基于TCP协议。
方法:QTcpSocket
连接双方:QTcpSocket作为连接实例。一次连接使用一个socket。使用connectToHost()连接到服务器。
服务器监听:使用QTcpServer,用于监听指定接口。连接使用事件驱动,有新连接时发送newConnection()信号。
发送:write()
接收:bytesAvread(),QIODevice类的读写方式。
示例:
客户端:
void MainWindow::tcpClient()
{
QTcpSocket *pClient = new QTcpSocket(this);
connect(pClient,SIGNAL(connected()),this,SLOT(handleConnect()));
connect(pClient,SIGNAL(readyRead()),this,SLOT(handleRead ()));
connect(pClient,SIGNAL(error(QAbstractSocket::SocketError)),
this,SLOT(displayError(QAbstractSocket::SocketError)));
pClient->abort();
pClient->connectToHost(QHostAddress::LocalHost,12306);
}
voidMainWindow::displayError(QAbstractSocket::SocketError error){
qDebug()<<"error"<<error;
}
void MainWindow::handleRead()
{
QTcpSocket *pClient = (QTcpSocket *)sender();
if(pClient->bytesAvailable()){
qDebug()<<"server:"<<pClient->readAll();
}
}
voidMainWindow::handleConnect()
{
QTcpSocket *pClient = (QTcpSocket *)sender();
pClient->write("abcd-tcp");
if(pClient->bytesAvailable()){
qDebug()<<pClient->read(100);
}
}
服务端:
void MainWindow::receiveTcp()
{
QTcpServer *pTcp = new QTcpServer(this);
if(!pTcp->listen(QHostAddress::LocalHost,12306)){
qDebug()<<pTcp->errorString();
}
qDebug()<<"listening..."<<pTcp->isListening()<<pTcp->serverAddress();
connect(pTcp,SIGNAL(newConnection()),this,SLOT(handleTcp()));
}
void MainWindow::handleTcp()
{
QTcpServer *pTcp = (QTcpServer *)sender();
QTcpSocket *pSocket =pTcp->nextPendingConnection();
if(pSocket)
{
connect(pSocket,SIGNAL(readyRead()),this,SLOT(handleClientData()));
qDebug()<<pSocket->peerAddress()<<pSocket->peerPort()<<pSocket->peerName();
}
}
void MainWindow::handleClientData()
{
QTcpSocket *pSocket = (QTcpSocket*)sender();
if(pSocket->bytesAvailable())
{
qDebug()<<pSocket->peerAddress()<<pSocket->peerPort()<<pSocket->peerName();
qDebug()<<pSocket->readAll();
pSocket->write("xxx-ubuntu");
}
}
原理:基于开源项目(WebKit)开发的浏览器。
方法:QtWebKit。
浏览器对象:QWebView(控件)。
页面对象:QWebPage。
DOM:QWebFrame,QWebElement。
历史记录:QWebHistoryItem。
示例:
ui->webView->load(QUrl("http://www.baidu.com/"));
sf2gis@163.com
2015年5月2日
1 目标:在网络上不同的计算机之间进行交互。
原理:构造不同的传输协议,在不同的主机之间进行按照协议标准进行请求和回复。方法:HTTP,FTP,TCP,UDP
使用QtNetwork框架的相关类操作。
1.1 Qt 操作
协议管理:使用QUrl进行Url构造,包含对协议、用户名、密码等设置。请求:QNetworkRequest。
回复:QNetworkReply。
操作管理:QNetworkAccessManager。负责进行HTTP操作及状态。
进度:QNetworkReply发送downloadProgress()信号。
1.2 示例
1.2.1 Http请求页面
voidMainWindow::http(){
QNetworkAccessManager *pManager = newQNetworkAccessManager(this);
connect(pManager,SIGNAL(finished(QNetworkReply*)),this,SLOT(handleReply(QNetworkReply*)));
QNetworkReply *reply =pManager->get(QNetworkRequest(QUrl("http://www.gfsoso.net/")));
connect(reply,SIGNAL(downloadProgress(qint64,qint64)),this,SLOT(handleProgress(qint64,qint64)));
}
voidMainWindow::handleReply(QNetworkReply *reply)
{
QString strReply(reply->readAll());
qDebug()<<strReply;
ui->textBrowser->setText(strReply);
reply->deleteLater();
}
voidMainWindow::handleProgress(qint64 readBytes,qint64 totalBytes)
{
ui->progressBar->setMaximum(totalBytes);
ui->progressBar->setValue(readBytes);
}
1.2.2 FTP下载文件
voidMainWindow::handleReply(QNetworkReply *reply){
QByteArray ba = reply->readAll();
QString strReply(ba);
qDebug()<<strReply;
ui->textBrowser->setText(strReply);
QFile file("test.tar.gz");
file.open(QFile::WriteOnly);
file.write(ba);
file.close();
reply->deleteLater();
}
voidMainWindow::handleProgress(qint64 readBytes,qint64 totalBytes)
{
ui->progressBar->setMaximum(totalBytes);
ui->progressBar->setValue(readBytes);
}
voidMainWindow::ftp()
{
QNetworkAccessManager *pManager = newQNetworkAccessManager(this);
connect(pManager,SIGNAL(finished(QNetworkReply*)),this,SLOT(handleReply(QNetworkReply*)));
QNetworkReply *reply =pManager->get(QNetworkRequest(QUrl("ftp://ftp.pku.edu.cn/open/db/MySQL/mysql-connector-java-5.1.21.tar.gz")));
connect(reply,SIGNAL(downloadProgress(qint64,qint64)),this,SLOT(handleProgress(qint64,qint64)));
}
2 Http :HypeText Tranfer Protoco,超文本传输协议
2.1 目标:发送和接收HTML。
2.2 方法:
提供多种操作方式,如get(请求URL),Post(请求处理数据),PUT(上传数据),DELETE(删除),CONNECT(连接到TCP/IP),OPTIONS(返回所有支持的方法),HEAD(仅返回头)。其中CURD对应POST,PUT,GET,DELETE。GET与POST的区别:get使用url的一部分传递参数,可见,长度有限(2048),只能传递ascii。post使用单独传递数据,不可见,长度不了,可传递二进制数据。
参考:http://www.w3school.com.cn/tags/html_ref_httpmethods.asp
http://zh.wikipedia.org/zh/%E8%B6%85%E6%96%87%E6%9C%AC%E4%BC%A0%E8%BE%93%E5%8D%8F%E8%AE%AE
REST和SOAP:目标简单的进行web service。REST使用HTTP方式CRUD,无状态,简单,安全性差,将所有对象抽象为资源,以URL进行请求。SOAP只使用POST,有状态,使用复杂,安全性好,将所有数据封装为XML进行交互。
参考:http://www.cnblogs.com/zhangz721/archive/2009/10/02/1577316.html
示例:参见Http请求页面
3 FTP :File Tranfer Protoco,文件传输协议
目标:文件在网络中的传输。方法:使用20端口传输文件,21端口传输命令。
参考:
http://zh.wikipedia.org/zh/%E6%96%87%E4%BB%B6%E4%BC%A0%E8%BE%93%E5%8D%8F%E8%AE%AE
3.1 Qt操作
Qt4使用QFtp,但是有消息丢失现象。Qt5之后建议使用QNetworkAccessManager。示例:参见FTP下载文件
参考:
http://blog.csdn.net/fuyoufang1/article/details/18215081
4 主机信息
目标:区分网络中不同的主机。原理:IP:internet protocol,互联网协议,为不同的主机分配唯一的ip地址。DNS(Domain NameService)将不同Url中名称解析为ip地址。IP地址有IPV4和IPV6两种。
子网掩码:区分不同局域网网段的掩码,过滤相同部分,以确定所属的网段。
网关:外部网络出口。局域网网络向外部发送数据时,会发送到网关,再由网关转发到目的网络。
参考:http://www.hackbase.com/tech/2015-01-12/70390.html
http://zh.wikipedia.org/wiki/%E7%BD%91%E5%85%B3
4.1 方法:QHostInfo。
获取域名的IP地址:QHostInfo::fromName(),同步获取;QHostInfo::lookupHost(“域名”),异步获取。获取IP地址的域名:QHostInfo::lookupHost(“IP地址”)。
示例:
void MainWindow::hostInfo()
{
qDebug()<<QHostInfo::localDomainName()<<","<<QHostInfo::localHostName();
qDebug()<<QHostInfo::fromName("www.baidu.com").addresses();
QHostInfo::lookupHost("www.baidu.com",this,SLOT(handleHost(QHostInfo)));
}
voidMainWindow::handleHost(const QHostInfo &hostInfo)
{
foreach(const QHostAddress&addr,hostInfo.addresses())
{
qDebug()<<addr.toString();
}
}
4.2 方法:QNetworkInterface,QNetworkAddressEntry。
网卡信息:QNetworkInterface,当前主机上所有网卡(包括虚拟)的信息。IP信息:QNetworkAddressEntry,每一个IP地址及其子网掩码和网关信息。
参考:http://blog.klniu.com/post/qnetworkinterface-class/
示例:
void MainWindow::interfaces()
{
qDebug()<<QNetworkInterface::allAddresses();
foreach(const QNetworkInterface&interface,QNetworkInterface::allInterfaces())
{
qDebug()<<"interface:"<<interface.name()<<interface.hardwareAddress();
foreach(const QNetworkAddressEntry&entry,interface.addressEntries())
{
qDebug()<<"Entry:"<<entry.ip()<<entry.netmask()<<entry.broadcast();
}
}
}
结果
(QHostAddress("fe80::2507:109f:3858:d133%15"), QHostAddress( "169.254.209.51" ) , QHostAddress( "192.168.22.1") , QHostAddress( "fe80::4cc6:bb45:659f:58a9%12" ) , QHostAddress("169.254.88.169" ) , QHostAddress( "192.168.1.102" ) ,QHostAddress( "fe80::254b:6d06:925:b6f5%20"
) , QHostAddress("192.168.206.1" ) , QHostAddress("fe80::8c8a:179b:ecb0:a9d3%22" ) , QHostAddress("192.168.217.1" ) , QHostAddress( "::1" ) , QHostAddress("127.0.0.1" ) , QHostAddress( "fe80::5efe:c0a8:d901%18" ) ,QHostAddress( "2001:0:9d38:6ab8:188f:ad3d:8a8d:71e3"
) , QHostAddress("fe80::188f:ad3d:8a8d:71e3%17" ) , QHostAddress( "fe80::5efe:c0a8:166%23") )
interface:"{6059E8E0-FCF5-4B12-9C6D-EC97B540E1AD}""44:6D:57:5E:95:73"
Entry: QHostAddress("fe80::2507:109f:3858:d133%15" ) QHostAddress("ffff:ffff:ffff:ffff::" ) QHostAddress( "" )
Entry: QHostAddress("169.254.209.51" ) QHostAddress( "" ) QHostAddress("" )
Entry: QHostAddress("192.168.22.1" ) QHostAddress( "" ) QHostAddress("" )
interface:"{253576A5-E502-4A9C-9394-88D45EE4B107}""00:21:CC:C8:A1:CF"
Entry: QHostAddress("fe80::4cc6:bb45:659f:58a9%12" ) QHostAddress( "ffff:ffff:ffff:ffff::") QHostAddress( "" )
Entry: QHostAddress("169.254.88.169" ) QHostAddress( "" ) QHostAddress("" )
interface:"{33AC696B-F917-423B-A17B-88AFFA264C4C}""44:6D:57:5E:95:73"
Entry: QHostAddress("192.168.1.102" ) QHostAddress( "255.255.255.0" )QHostAddress( "192.168.1.255" )
interface:"{A1696BDD-A453-4D81-9AFC-A22A7553EAAD}""00:50:56:C0:00:01"
Entry: QHostAddress("fe80::254b:6d06:925:b6f5%20" ) QHostAddress("ffff:ffff:ffff:ffff::" ) QHostAddress( "" )
Entry: QHostAddress("192.168.206.1" ) QHostAddress( "255.255.255.0" )QHostAddress( "192.168.206.255" )
interface:"{5F04202D-B1C9-4CD3-951F-F1FD4C091D2E}""00:50:56:C0:00:08"
Entry: QHostAddress("fe80::8c8a:179b:ecb0:a9d3%22" ) QHostAddress("ffff:ffff:ffff:ffff::" ) QHostAddress( "" )
Entry: QHostAddress("192.168.217.1" ) QHostAddress( "255.255.255.0" )QHostAddress( "192.168.217.255" )
interface:"{846EE342-7039-11DE-9D20-806E6F6E6963}" ""
Entry: QHostAddress("::1" ) QHostAddress("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" ) QHostAddress("" )
Entry: QHostAddress("127.0.0.1" ) QHostAddress( "" ) QHostAddress( "")
interface:"{E021EE1B-15F5-425A-92CE-685790FE0031}" "00:00:00:00:00:00:00:E0"
interface:"{31FDE048-BFF0-4DB6-9D80-4362D1CAE28F}""00:00:00:00:00:00:00:E0"
Entry: QHostAddress("fe80::5efe:c0a8:d901%18" ) QHostAddress("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" ) QHostAddress("" )
interface:"{C534E5AC-9EA2-4E25-8017-8F5628B7338D}""00:00:00:00:00:00:00:E0"
Entry: QHostAddress("2001:0:9d38:6ab8:188f:ad3d:8a8d:71e3" ) QHostAddress( "::") QHostAddress( "" )
Entry: QHostAddress("fe80::188f:ad3d:8a8d:71e3%17" ) QHostAddress("ffff:ffff::" ) QHostAddress( "" )
interface: "{E858920C-9CEA-4C35-9F85-9609D71CA21D}""00:00:00:00:00:00:00:E0"
interface:"{3B61355E-6D8F-441F-9379-020F9551733B}""00:00:00:00:00:00:00:E0"
interface:"{7E8F026C-AA3B-4F39-AA8E-5726B3382763}""00:00:00:00:00:00:00:E0"
interface:"{3D3A432C-5A7E-4E00-BA86-EE4309C419EF}""00:00:00:00:00:00:00:E0"
Entry: QHostAddress("fe80::5efe:c0a8:166%23" ) QHostAddress("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" ) QHostAddress("" )
5 UDP:用户数据报协议,User Datagram Protocol
目标:简单快速的传输数据。原理:发送方设置数据及其相关信息(发送方地址:端口,目标地址:端口,长度,校验,数据等)打包发送,不再处理其它问题。
端口:目标是区分指同一协议下的不同连接。0~65535,1024之下系统保留,应尽量使用大的端口号。
参考:http://www.nwnu.edu.cn/Article.do_id=301.html
方法:UDP,短小快速,数据量应该尽量少,一般不要超过512B。
监听指定IP:Port:bind()。只有服务端需要绑定端口以固定收发地址,客户端动态绑定。
发送数据:writeDatagram直接发送,动态绑定端口。
接收数据:事件驱动,发送readyRead()消息。hasPendingDatagram()检测是否有数据,readDatagram()读取数据。
示例:
发送方:ip=192.168.1.102
void MainWindow::udpSender()
{
QUdpSocket *pSender = new QUdpSocket(this);
QByteArray ba("againxx");
pSender->writeDatagram(ba,QHostAddress("192.168.217.129"),12306);
}
接收方:ip=192.168.217.129
void MainWindow::receive()
{
QUdpSocket *pUdp = new QUdpSocket(this);
pUdp->bind(12306,QAbstractSocket::ShareAddress);
connect(pUdp,SIGNAL(readyRead()),this,SLOT(handleUdpData()));
m_pUdp = pUdp;
}
voidMainWindow::handleUdpData()
{
while(m_pUdp->hasPendingDatagrams())
{
int iSize=m_pUdp->pendingDatagramSize();
QByteArray baDatagram;
baDatagram.resize(iSize);
QHostAddress host;
quint16 port;
m_pUdp->readDatagram(baDatagram.data(),iSize,&host,&port);
qDebug()<<"receive-"<<host.toString()<<":"<<port<<"="<<baDatagram;
}
}
6 TCP:传输控制协议,Transformation Control Protocol
目标:稳定的连接传输。可重复发送、校验数据。原理:底层协议,HTTP,FTP等都是基于TCP协议。
方法:QTcpSocket
连接双方:QTcpSocket作为连接实例。一次连接使用一个socket。使用connectToHost()连接到服务器。
服务器监听:使用QTcpServer,用于监听指定接口。连接使用事件驱动,有新连接时发送newConnection()信号。
发送:write()
接收:bytesAvread(),QIODevice类的读写方式。
示例:
客户端:
void MainWindow::tcpClient()
{
QTcpSocket *pClient = new QTcpSocket(this);
connect(pClient,SIGNAL(connected()),this,SLOT(handleConnect()));
connect(pClient,SIGNAL(readyRead()),this,SLOT(handleRead ()));
connect(pClient,SIGNAL(error(QAbstractSocket::SocketError)),
this,SLOT(displayError(QAbstractSocket::SocketError)));
pClient->abort();
pClient->connectToHost(QHostAddress::LocalHost,12306);
}
voidMainWindow::displayError(QAbstractSocket::SocketError error){
qDebug()<<"error"<<error;
}
void MainWindow::handleRead()
{
QTcpSocket *pClient = (QTcpSocket *)sender();
if(pClient->bytesAvailable()){
qDebug()<<"server:"<<pClient->readAll();
}
}
voidMainWindow::handleConnect()
{
QTcpSocket *pClient = (QTcpSocket *)sender();
pClient->write("abcd-tcp");
if(pClient->bytesAvailable()){
qDebug()<<pClient->read(100);
}
}
服务端:
void MainWindow::receiveTcp()
{
QTcpServer *pTcp = new QTcpServer(this);
if(!pTcp->listen(QHostAddress::LocalHost,12306)){
qDebug()<<pTcp->errorString();
}
qDebug()<<"listening..."<<pTcp->isListening()<<pTcp->serverAddress();
connect(pTcp,SIGNAL(newConnection()),this,SLOT(handleTcp()));
}
void MainWindow::handleTcp()
{
QTcpServer *pTcp = (QTcpServer *)sender();
QTcpSocket *pSocket =pTcp->nextPendingConnection();
if(pSocket)
{
connect(pSocket,SIGNAL(readyRead()),this,SLOT(handleClientData()));
qDebug()<<pSocket->peerAddress()<<pSocket->peerPort()<<pSocket->peerName();
}
}
void MainWindow::handleClientData()
{
QTcpSocket *pSocket = (QTcpSocket*)sender();
if(pSocket->bytesAvailable())
{
qDebug()<<pSocket->peerAddress()<<pSocket->peerPort()<<pSocket->peerName();
qDebug()<<pSocket->readAll();
pSocket->write("xxx-ubuntu");
}
}
7 浏览器:WebKit
目标:创建能够浏览网页的浏览器,可能解析HTML、CSS、JavaScript等。原理:基于开源项目(WebKit)开发的浏览器。
方法:QtWebKit。
浏览器对象:QWebView(控件)。
页面对象:QWebPage。
DOM:QWebFrame,QWebElement。
历史记录:QWebHistoryItem。
示例:
ui->webView->load(QUrl("http://www.baidu.com/"));
相关文章推荐
- PyQt
- Qt线程
- 通过线程控制QT控制台程序退出
- QT编译时 qmake错误
- 读Pyqt4教程,带你入门Pyqt4 _006
- 基于qt的嵌入式平台输入法:SYSZUXpinyin移植到arm后,UDP接收端中文乱码 本地中文乱码 解决
- QT多线程—主界面卡死解决方案
- QT中进度对话框(QProgressDialog)
- PyQt5资料
- Qt小游戏开发:贪吃蛇
- 在Qt Creator中配置Opencv的详细步骤
- VS2013配置qt开发环境及安装包(qt5.3.2)
- QT配置opencv开发环境
- 编译生成ARM上可运行的Qt程序
- QT 的信号与槽机制介绍
- qt5中文乱码
- win7 64位 QT安装 MySql数据库驱动安装遇到的问题
- QTP数据库操作(ADO)(转载)
- 使用QTP&nbsp;11批量修改QC10测试…
- 使用QC10远程启用QTP11(也可在本…