void DataUnpacket::run( )
{
m_pSocket = new QTcpSocket
//m_pSocket->socketOption(QAbstractSocket::LowDelayOption)
QString ip("192.168.112.100")
ushort portData = 5001
m_pSocket->connectToHost( ip, portData )
m_pSocket->waitForConnected()
if( QAbstractSocket::ConnectedState != m_pSocket->state() )//判断是否连接成功
return
while( m_bRunning )
{
if( m_pSocket->bytesAvailable() >0)
{
QByteArray arr = m_pSocket->readAll()//这不进,
qDebug() <<"recv len =" <<arr.length()
}
else
{
m_pSocket->write("test",4)
m_pSocket->flush()// 可以发送出去
QThread::usleep(1000)
}
}
}
方法二 movethred 效果 一样
方法三 SocketQThread中使用 QtConcurrent::run创建线程, 这个使用QTCreater 调试没有问题,这个也是大坑
打包会出现不能接收到数据或者没发出凳绝去, wireshark检测有时会出现现象接收到数据但没发出去
int SocketQThread::InitTest( )
{
int re = 0
QString ip("192.168.112.5")
ushort portData = 5001
m_pDataPackage.resize(1)
m_pDataPackage[0] = new DataUnpacket
if( !m_pDataPackage[0]->InitSocket(ip,portData ) )
re = -1
return re
}
void SocketQThread::stratThred()
{
含州 m_running = true
for(int i=0i<1i++)//测试
{
QtConcurrent::run(this, &SocketQThread::recvDataThread, i )
}
}
void SocketQThread::stopThred()
{
m_running = false
for(int i=0i<1i++)//测试
{
m_pDataPackage[0]->CloseFile( )
m_pDataPackage[0]->枣老姿tcpDisconnect( )
}
}
void SocketQThread::recvDataThread( int ch )//暂定
{
DataUnpacket* pPackage = m_pDataPackage[ch]
while( m_running )
{
if( pPackage->SocketBytesAvailable() >0)
pPackage->RecvData()
else
QThread::usleep(1)
}
}
类DataUnpacket 继承 Cpackage 如下:
m_Socket为Cpackage的成员变量
int DataUnpacket::RecvData( )
{
int re = 0
QByteArray reArr
QByteArray arr = m_Socket.readAll()
qDebug() <<"recv len =" <<arr.length()
#if 0
m_Socket.write(arr )
m_Socket.flush()//不加发不出去
#else
QMetaObject::invokeMethod( &m_Socket, std::bind( static_cast<qint64(QTcpSocket::*)(const QByteArray &) >( &QTcpSocket::write ),&m_Socket, arr ))//, Qt::DirectConnection
//若加 Qt::DirectConnection ,需要添加m_Socket.flush()/
return re
}
bool Cpackage::InitSocket(QString&ip, ushort&port )
{
bool tf = true
m_Socket.connectToHost( ip, port )
m_Socket.waitForConnected()
if( QAbstractSocket::ConnectedState != m_Socket.state() )//判断是否连接成功
tf = false
return tf
}
void Cpackage::tcpDisconnect( )
{
if( m_Socket.state() == QAbstractSocket::ConnectedState) //关闭时,确保与服务器断开连接
m_Socket.disconnectFromHost()
}
方法四 QtConcurrent::run(this, &DataUnpacket::RecvDataTest) 这个
void testData::RecvDataTest()
{
m_pSocket = new QTcpSocket(this)
//m_pSocket->socketOption(QAbstractSocket::LowDelayOption)
QString ip("192.168.112.100")
ushort portData = 5001
m_pSocket->connectToHost( ip, portData )
m_pSocket->waitForConnected()
if( QAbstractSocket::ConnectedState != m_pSocket->state() )//判断是否连接成功
return
while( m_bRunning )
{
if( m_pSocket->bytesAvailable() >0)
{
QByteArray arr = m_pSocket->readAll()//这不进,
qDebug() <<"recv len =" <<arr.length()
}
else
{
m_pSocket->write("test",4)
m_pSocket->flush()//可以发送出去
QThread::usleep(1000)
}
}
}
如下例子 是可以的
void testData::RecvDataTest()
{
qDebug() <<QThread::currentThread()
QByteArray arr = m_pSocket->readAll()//这不进,
qDebug() <<"recv len =" <<arr.length()
m_pSocket->write("test",4)
}
void testData::stratThred( bool tf )
{
if( tf )
start()
else
exit()
}
void testData::run( )
{
qDebug() <<"stratThred" <<QThread::currentThread()
if( nullptr == m_pSocket )
{
m_pSocket = new QTcpSocket
connect(m_pSocket, SIGNAL(readyRead()), this, SLOT(RecvDataTest()), Qt::DirectConnection)
//m_pSocket->socketOption(QAbstractSocket::LowDelayOption)
}
m_pSocket->connectToHost( QString("192.168.112.100"), 5001 )
m_pSocket->waitForConnected()
if( QAbstractSocket::ConnectedState != m_pSocket->state() )//判断是否连接成功
return
//m_pSocket->waitForReadyRead(1000)
exec()
m_pSocket->disconnectFromHost()
}
这是因为文件路径不对造成的,解决方法如下:
1、首先pro文件配置:Qt网络功能需要在谨前pro文件增加网络库。
2、QTcpServer服务端建立的方法代码,如下图所示。
3、QTcpServer当有新客户端连接时,会发出QTcpServer::newConnection的信号方法代码。
4、客户端为主动连接方不需要监听,直接建立QTcpSocket代码。
5、最后通过connectToHost连接指定ip和端口,将socket的连接成功的信号与对应槽连接,当连接成功可以祥州清将自定义迹让的标记位置为true。
关于这个问题折腾了我好久,以前做些小练习的时候,用QTcpSocket的write()一数据,然后接收方只要emit一个readyread()信号然后就用让枝QTcpSocket的read()去读。本以为只要发送方write一次,接收方就会响应readyRead信号。其实根本就不是这样的,readyRead不会知道发送方调用了几个write,它只负责在有数据到达时触发,等你真正接收时,或许已经能够收到所有的数据了。这要看你发送的信息量了,如果很少的话,比如发送几个字节的数据当然没有问题,一次readyRead就能读到所有数据但切记,这不是必然的!另外readRead到底能读多少数据是不尺滑帆确定的,这要看你的网速情况,还有你的电脑的性能了。举个例子,我在编程时用发送方while()连续向网络上传输数据,这个文件的数据量很大,就要使用waitForBytesWritten做一下等陵雹待,这就是每次等上一个write()完毕后才继续下一个write()这样数据就不会漏或者乱。还有一个问题是要传输数据时一定要先告诉接收方发的数据量是多大,也就是在发真正的数据时的头部用2个字节(quint16)或四个字节(quint32)去存放传送数据的大小。接收方就是根据这个传输数据的大小和每次bytesAvailable()的大小做对比若小就不断的触发emit的信号,在去接收,知道最终接收的总数据跟发送方的数据大小是一致的就说明接收完毕。这就解决了大数据量连续发送与接收的问题。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)