[SOLVED]Need Help:structure over socket
-
Litle example for your struct:
in *.h file
@struct structName
{
int varint;
char varchar [10];
};
QDataStream &operator <<(QDataStream &out,const structName &dataStruct);
QDataStream &operator >>(QDataStream &in, structName &dataStruct);@in *.cpp file
@QDataStream &operator <<(QDataStream &out,const structName &dataStruct)
{
out << dataStruct.varint;
out.writeRawData ( dataStruct.varchar, 10 );
return out;
}QDataStream &operator >>(QDataStream &in, structName &dataStruct)
{
dataStruct = structName();
in >> dataStruct.varint;
in.readRawData ( dataStruct.varchar, 10 )
return in;
}@didn't test it but i think it should work.
-
Note that QDataStream may add metadata into the stream for its own use. You will not see it, but this may be a problem if your application has to be compatible with other non-Qt clients or if you have to implement a defined wire-protocol.
-
I have successfully transmit the structured data over
the network with this "transmit function".@void Client::transmit()
{
structName structCall;structCall.varint = 5;
structCall.varchar [10] ='AaBbCcDdEeFf';socket->write(structCall.varint + structCall.varchar [10] );
}
@
Now, how can I put the structured data (databytes)
that this "receive function" is receiving from socket to update the "structName structCall".
@
void Client::receive()
{
structName structCall;
qDebug() << "DATA" << socket->readAll();
}
@
I am hoping somebody could help me with this situation.Am... I have also a question. what is the correct way of sending the datastruct to a socket.
as you can see in my "transmit() function" I have used
@socket->write(structCall.varint + structCall.varchar [10] );@is there a simpler way in sending my entire struct over a network?
like:
@socket->write(structcall);@ -
sorry, if I did not stated my problem clearly.
Alright, this is my "receive function".
@
void Client::receiveMessage()
{
qint64 bytes = buffer->write(socket->readAll());
buffer->seek(buffer->pos() - bytes);QString structContainer = buffer->readAll(); qDebug() << structContainer; structName structCall;
}
@so, how can I put the values of "structContainer" to my structCall?
thanks -
Here is the implementation of idea:
@void transmit()
{
structName structCall;
structCall.varint = 5;
structCall.varchar [10] ='AaBbCcDdEeFf';QByteArray sendArray; QDataStream out(&sendArray,QIODevice::WriteOnly); out.setVersion(QDataStream::Qt_4_8); out << structCall; socket->write(sendArray);
}
void receiveMessage()
{
QByteArray receiveArray;
structName structCall;
receiveArray.append(socket->readAll());QDataStream in(&receiveArray,QIODevice::ReadOnly); in.setVersion(QDataStream::Qt_4_8); in >> structCall;
}@
You should make some modifications and write few checks for correct data.
Is it what you ask? -
[quote author="qxoz" date="1362637580"]Here is the implementation of idea:
@void transmit()
{
structName structCall;
structCall.varint = 5;
structCall.varchar [10] ='AaBbCcDdEeFf';QByteArray sendArray; QDataStream out(&sendArray,QIODevice::WriteOnly); out.setVersion(QDataStream::Qt_4_8); out << request; socket->write(sendArray);
}@
[/quote]
I think in line 10 of the transmit function its supposed to be out << structCall ? -
This is exactly what I am looking for.
But I noticed, when I try to send the data.
for example:
I give varint with a value of 5 on my "transmit function"
@
structCall.varint = 5;
socket->write(sendArray);
qDebug() << "DATA" << sendArray;
@and my "Application Output" reported:
"DATA 00000005"And it actually sends "00000005" data instead of "05" data only over the socket.
so, what should I do to eliminate the first "000000" and enable me to send only "05".thanks qxoz, you save a lot of time of me.
-
I don't quite get the roundtrip through QByteArray, to be honest. QStreamWriter can operate directly on the socket...
Anyway, I will assume your implementation of the streaming operator for your structName is still like this:
@
QDataStream &operator <<(QDataStream &out,const structName &dataStruct)
{
out << dataStruct.varint;
out.writeRawData ( dataStruct.varchar, 10 );
return out;
}
@Here, you first output the int. You are using a plain int, but I'd recommend to always use variables with a guaranteed size for these purposes. int normally is the same as qint32. So, you have a 32 bits (four bytes) value. You will need to send all of these bytes in the stream. If your value has a smaller range, you should use a smaller data type like quint16 or qint8. Otherwise, on the receiving side, there is no way to know how to read in the data again. Note that this is binary data, not text that you are seeing.
-
/teacher mode...
QDataStream is a class that is meant to operate on a [[doc:QIODevice]]. The socket is such an IO device. If you use it on a QByteArray, it actually creates a [[doc:QBuffer]] in the background. QBuffer is a class that provides a QIODevice interface on a QByteArray.
-
@struct your_structure
{
//variables
},test@When you want to send the structure:
@char * sendPack = (char *)&test;
writeDatagram((const char *)sendPack,sizeof(your_structure),destIP,destPORT);@When you want to receive the packet:
@char recPack[sizeof(your_structure)];
readDatagram((char *)&inPack, sizeof(your_structure),senderIP, senderPort);
your_structure * inp = new your_structure();
inp = (your_structure *)inPack;@ -
[quote author="vahidnateghi" date="1383463791"]@struct your_structure
{
//variables
},test@When you want to send the structure:
@char * sendPack = (char *)&test;
writeDatagram((const char *)sendPack,sizeof(your_structure),destIP,destPORT);@When you want to receive the packet:
@char recPack[sizeof(your_structure)];
readDatagram((char *)&inPack, sizeof(your_structure),senderIP, senderPort);
your_structure * inp = new your_structure();
inp = (your_structure *)inPack;@[/quote]That won't work if you're on different architectures, like trying to communicate between a 32 bits and a 64 bits version of your application, to name just one possible problem with this approach. My advise: never, ever do it this way.