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();
}