在QT下连续发送结构体问题;
前言:
在我之前写的代码中,我通常是使用socket来实现服务器与客户端之间得通信或发送数据,在服务器端中用recv一直阻塞等待客户端的send指令。而进入qt平台,qt中的信号与槽机构我觉得非常好玩,而qt中得网络通信我也发现了和之前在vs下的不同;qt中用write发送数据给服务器,服务器端通过readyRead()信号判断客户端是否有数据传来,当信号触发,触发槽函数(我自己写的action()函数,用来解析发送来的结构体中的指令)
结构体如下
struct Data
{
int work;//操作指令
char name[30];//为方便这里只放一个字符串
};
connect中的信号与槽
connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(action()));
在一般情况下,客户端通过结构体发送一个指令,如下
tcpSocket->write((char*)&m_data,sizeof(Data));
服务器端readyRead()知道客户端发来数据,操作如下
connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(action()));
void Widget::action()
{
quint16 size = sizeof(Data);
if(tcpSocket->bytesAvailable() < size)//返回当前已经获得的数据的大小
{
return;
}
QByteArray array = tcpSocket->readAll();//全部接收
if(!array.isEmpty())
{
memcpy(&data,array,sizeof(Data));//数据转换,这里的data在头文件类中声明,这里不赘述
switch(data.work)
{
/**/
/**/
/**/
}
}
刚开始,客户端发来的指令都没有问题,但当要实现像客户端要连续发送结构体到服务器时就出现了问题——–永远只接收到第一次发送的结构体,后面的都被吃了?一开始百思不得其解,加延迟加waitForBytesWritten都没用,无奈百度了半天终于找到了原因:
链接
这让我意识到了问题所在,原来连续发送了这么多,,服务器端一次性全给接收了,不像之前写的一个recv只对应一个send。所以根据我的情况,我便在要连续发送结构体前先发送一个信息告知服务器接下来会有几个结构体要来,这样便解决了连续发送结构体只会显示第一次发送的问题了:
发送代码
void Widget::on_sendDataButton_clicked()
{
Data data;
char buf[64];
int num = 0;//num来记录结构体个数
for(int i = 65; i < 75; ++i)
{
++num;
sprintf(buf,"test_%c",i);
strcpy(data.name,buf);
testData.push_back(data);
}
char ch = num + '0';//转换为char型便于发送
tcpSocket->write((char* )&ch,sizeof(char));
for(int i = 0; i < testData.size();++i)
{
Data m_data;
m_data = testData.at(i);
tcpSocket->write((char*)&m_data,sizeof(Data));
}
}
接收代码
void Widget::action()
{
quint16 size = sizeof(Data);
if(tcpSocket->bytesAvailable() < size)
{
return;
}
QByteArray array = tcpSocket->readAll();
if(!array.isEmpty())
{
char ch;
char *buf = array.data();
memcpy(&ch,array,sizeof(char));
int num = ch - '0';//将其转换回来
int i = 0;//当memcpy完哟个结构体,需要跳至下一个结构体首地址,这时用i来实现跳跃
buf = buf + 1;//使跳过第一位,因为放着结构体个数
while(num)
{
Data data;
memcpy(&data,buf + sizeof(Data) * i,sizeof(Data));
qDebug()<<data.name;
--num;
++i;
}
}
}
输出结果如下,可见功能已经实现