图片为测试每次发送长度 1024*1024 Byte数据的延时,每次间隔20毫秒,同一台电脑,WIN10系统,32G内存,24核心; 测试代码用QT自带例子修改。
结果:
TCP/IP 延时30毫秒左右,
DBUS 延时超过100毫秒,连续次数越多时差和延时越大;
DBUS 优点是保证每次收发成功,作为指令收发、短数据(512B)收发还是可以的,建议要间隔500毫秒以上;
TCP/IP 优点快,想保证收发数据,就要自己写协议了,下面的保证收发的简单代码,点对点的发送。
突发数据 TCP/IP 一样比 DBUS 反应快,DBUS需要服务转发。
但是在本地进程通信数据量大的情况,最好使用(DBUS+内存共享)的方式,这样速度不比TCP/IP的差,大数据时反而更有优势。如:FastDDS、OpenDDS本地进程通信也使用共享内存。
// dbus 发送数据
void Controller::on_pushButton_clicked()
{
QDBusVariant data;
uint size =0;
qlonglong time = QDateTime::currentMSecsSinceEpoch();
QVariant m_variant;
QByteArray m_ByteArray( 1024*1024, Qt::Uninitialized );
m_variant.setValue( m_ByteArray );
data.setVariant( m_variant );
car->sendData( data, size, time );
}
// dbus 接收数据
void Car::sendData(const QDBusVariant &data, uint size, qlonglong time)
{
qlonglong ti=QDateTime::currentMSecsSinceEpoch();
static double count =0;
static double tis=0; // 时差累计
static double tiss=0; // 时差
static double tism=0; // 最大时差
tiss=(ti-time);
tis+=tiss;
count+=1;
tism = tism<tiss? tiss:tism;
qDebug()<<time<<ti<<tism<<tiss<<count<<(tis/count);
}
// dbus xml 配置
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node name="/com/trollech/examples/car">
<interface name="org.example.Examples.CarInterface">
<method name="accelerate"/>
<method name="decelerate"/>
<method name="turnLeft"/>
<method name="turnRight"/>
<method name="sendData">
<arg name="data" type="v" direction="in"/>
<arg name="size" type="u" direction="in"/>
<arg name="time" type="x" direction="in"/>
</method>
<signal name="crashed"/>
</interface>
</node>
// TCP/IP 发送数据
void Server::sendData( )
{
static bool ss=false;
static QMutex Mutex;
qApp->processEvents();
// if(ss)
// return ;
// ss=true;
// Mutex.lock();
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_0);
volatile uint size ;//=qrand() % fortunes.size();
volatile qlonglong time;
QByteArray m_ByteArray( 1024*1024, Qt::Uninitialized );
size = qrand() % fortunes.size();
time = QDateTime::currentMSecsSinceEpoch();
uint ii=(m_ByteArray.size()+sizeof (qlonglong) +fortunes.at(size).size() );
out <<ii<<time<<m_ByteArray<<fortunes.at(size);
uint ic=block.size();
block.insert(0,(char*)&ic,4);
clientConnection->write(block);
// clientConnection->flush();
// Mutex.unlock();
// ss=false;
qDebug()<<ic<<ii<<time;
}
// TCP/IP 接收数据
void Client::readFortune()
{
loop_read:
static uint si = 0;
if(tcpSocket->bytesAvailable()<4)
{
si = 0;
return ;
}
if(si==0)
{
tcpSocket->read( (char*)&si, 4);
}
if( tcpSocket->bytesAvailable()<si )
return ;
QString nextFortune;
in.startTransaction();
QByteArray m_ByteArray;
uint size = 0;
qlonglong time;
in >> size>>time>>m_ByteArray>>nextFortune;
si = 0;
qlonglong ti=QDateTime::currentMSecsSinceEpoch();
static double count =0;
static double tis=0;
static double tiss=0;
static double tism=0;
tiss=(ti-time);
tis+=tiss;
count+=1;
tism = tism<tiss? tiss:tism;
qDebug()<<time<<ti<<tism<<tiss<<count<<(tis/count)<<nextFortune;
if(tcpSocket->bytesAvailable()>=4)
goto loop_read;
if (!in.commitTransaction())
return;
if (nextFortune == currentFortune) {
QTimer::singleShot(0, this, &Client::requestNewFortune);
return;
}
currentFortune = nextFortune;
statusLabel->setText(currentFortune);
getFortuneButton->setEnabled(true);
}