OpenHW12手记--Qt网络服务(TCP UDP)的建立与使用

来源:互联网 发布:mac顶部菜单栏图标 编辑:程序博客网 时间:2024/06/03 23:47
Qt是跨平台C++图形用户界面应用程序开发框架,它既可以开发GUI程式,也可用于开发非GUI程式,它拥有很丰富的C++库,可以应用于应用程序开发的各个方面。在网络通信方面,Qt已经封装了很多Tcp Udp操作函数,只需要对类进行简单操作就可以完成网络通信功能,这里总结了Qt环境下UDP和TCP操作的基本步骤。
UDP网络通信及数据传输
UDP发送端:
#include
QUdpSocket *sender;
sender = new QUdpSocket(this);
 
QByteArray datagram = “hello world!”;
 
//UDP广播
sender->writeDatagram(datagram.data(),datagram.size(),QHostAddress::Broadcast,6665);
 
//向特定IP发送
QHostAddress serverAddress = QHostAddress("10.21.11.66");
sender->writeDatagram(datagram.data(), datagram.size(),serverAddress, 6665);
 
/* writeDatagram函数原型,发送成功返回字节数,否则-1
qint64 writeDatagram(const char *data,qint64 size,const QHostAddress &address,quint16 port)
qint64 writeDatagram(const QByteArray &datagram,const QHostAddress &host,quint16 port)
*/


UDP接收端:
#include
QUdpSocket *receiver;
 
//信号槽
private slots: 
    void readPendingDatagrams();
 
receiver = new QUdpSocket(this);
//接收套接字(receiver)可以从绑定(bind())的主机和端口读取数据,这里QHostAddress::LocalHost表示本地主机的特殊地址;若不指定地址,receiver将接收此机器上发往任意IP地址的数据报。
//采用ShareAddress模式(即允许其它的服务连接到相同的地址和端口,特别是用在多客户端监听同一个服务器端口等时特别有效),和ReuseAddressHint模式(重新连接服务器)

receiver->bind(QHostAddress::LocalHost, 6665, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint );
connect(receiver, SIGNAL(readyRead()),this, SLOT(readPendingDatagrams()));
 
//pendingDatagramSize()函数返回第一个第一个待处理数据报大小。从应用程序角度看,数据报总是作为一个单一的数据单元来发送和接收的,这意味着只要有任意字节数据可用,就认为整个数据报可以被读取。readDatagram()调用把第一个待处理的数据报的内容复制到指定的char*缓冲区中(若缓冲区空间太小,就直接截断数据),并且前移至下一个待处理的数据报。
void readPendingDatagrams()
 {
     while (receiver->hasPendingDatagrams()) {
         QByteArray datagram;
         datagram.resize(receiver->pendingDatagramSize());
         receiver->readDatagram(datagram.data(), datagram.size());
         //数据接收在datagram里
/* readDatagram 函数原型
qint64 readDatagram(char *data,qint64 maxSize,QHostAddress *address=0,quint16 *port=0)
*/
     }
 }
关闭套接字使用 receiver->close();

// 获取ip地址,获取本机ip地址(其协议为ipv4的ip地址)
//QList是Qt中一个容器模板类,是一个数组指针?
QList list = QNetworkInterface::allAddresses();//此处的所有地址是指ipv4和ipv6的地址
//foreach (variable, container),此处为按照容器list中条目的顺序进行迭代
foreach (QHostAddress address, list) {    
   if(address.protocol() == QAbstractSocket::IPv4Protocol)
       return address.toString();
}
QString localHostName = QHostInfo::localHostName();//返回主机名,QHostInfo包含了一些关于主机的静态函数


TCP网络通信及数据传输
服务器端(Server):
#include
QTcpServer *tcpServer ;
QTcpSocket *clientConnection;

tcpServer = new QTcpServer();
//开始侦听端口
//tcpServer->listen(QHostAddress::Any, 6665);
if ( !tcpServer->listen(QHostAddress::LocalHost,6666))
 //监听本地主机的6666端口,如果出错就输出错误信息,并关闭
    qDebug() << tcpServer->errorString();
    tcpServer ->close();
}
//连接信号和槽函数,当server有新连接被建立时发射newConnection()信号调用acceptConnection()函数
connect(tcpServer, SIGNAL(newConnection()), this, SLOT(acceptConnection()));

void acceptConnection()
{
    //获取已经建立的连接的子套接字
    clientConnection = tcpServer->nextPendingConnection();
    connect(clientConnection, SIGNAL(readyRead()), this, SLOT(readClient()));
    //失去(或关闭)连接后删除该套接字clientConnection
    connect(clientConnection,SIGNAL(disconnected()),clientConnection,SLOT(deleteLater()));
    //当数据发送成功时触发
    connect(clientConnection,SIGNAL(bytesWritten(qint64)),this,SLOT(updateClientProgress(qint64)));
}
//若要断开连接,调用clientConnection->disconnectFromHost()发出disconnected()信号

void readClient()
{
    QString str = clientConnection->readAll();
    //或者
    char buf[1024];
    clientConnection->read(buf,1024);
}


客户端(Client):
#include
QTcpSocket * tcpClient ;
char *data="hello qt!";
client = new QTcpSocket(this);

//当连接服务器成功时,发出connected()信号
connect(tcpClient,SIGNAL(connected()),this,SLOT(startTransfer()));
//有数据到来时发出readyRead()信号
connect( tcpClient ,SIGNAL(readyRead()),this,SLOT(readMessage()));
//当有数据发送成功时,发出bytesWritten(qint64)信号
connect(tcpClient,SIGNAL(bytesWritten(qint64)),this,SLOT(updateClientProgress(qint64)));
//当连接出现问题时就会发出error(QAbstractSocket::SocketError)信号,这时就会执行displayError()函数
connect(tcpClient,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(displayError(QAbstractSocket::SocketError)));

//connectToHost调用是异步的,总是立即返回。若连接建立起来并运行,QTcpSocket发射connect()信号;若连接失败则发射error(QAbstractSocket::SocketError)信号。
tcpClient->connectToHost(QHostAddress("10.21.11.66"), 6665);
tcpClient->write(data);

void Widget::displayError(QAbstractSocket::SocketError) //显示错误
{
    qDebug() << tcpClient->errorString();
    tcpClient->close();
}
0 0
原创粉丝点击