Alexies, как вам идея создания транспортного протокола под наши задачи?
http://vk.com/doc295953584_375295824Не желаете поучаствовать в его разработке?
Дабы была совместимость.
Вот пример использования
Код:
#define LOW(val) (val&0x00ff)
#define HIGH(val) ((val&0xff00)>>8)
quint8 LasertagSystem::calculateCheckSun(QByteArray data)
{
quint8 sum;
sum=0;
for(int i=0;i<data.size() ; i++)
{
sum = sum^data.at(i);
}
return sum;
}
QByteArray LasertagSystem::transportHeader(QString preamble, uint8_t player_id, uint8_t team_id, uint16_t club_ID, uint16_t zone_id, uint16_t data_Length, uint8_t data_CS)
{
QByteArray result;
result.clear();
result.append(preamble);
result.append(player_id);
result.append(team_id);
result.append(LOW(club_ID));
result.append(HIGH(club_ID));
result.append(LOW(zone_id));
result.append(HIGH(zone_id));
result.append(LOW(data_Length));
result.append(HIGH(data_Length));
result.append(data_CS);
return result;
}
QByteArray LasertagSystem::createTransportPackage(QString preamble, uint8_t player_id, uint8_t team_id, uint16_t club_ID, uint16_t zone_id, QByteArray data)
{
QByteArray header;
qint8 dataCS;
qint8 headerCS;
dataCS = calculateCheckSun(data);
header = transportHeader(preamble, player_id, team_id, club_ID,zone_id,data.size(),dataCS);
headerCS = calculateCheckSun(header);
header.append(headerCS);
header.append(data);
return header;
}
void LasertagSystem::tcpSocketConnected()
{
QByteArray header, tmp;
setTcpServerLedSrc("qrc:/images/led-green-on.png");
emit tcpConnected();
tcpSocket->write("Hello!!!");
dataToTransport.clear();
dataToTransport.append("1234567890");
tcpSocket->write(createTransportPackage("@HSL",1,2,3,4,dataToTransport));
tcpSocket->write("MYCOP");
dataToTransport.clear();
dataToTransport.append("Test! Super test!!!");
tcpSocket->write(createTransportPackage("@HSL",1,2,3,4,dataToTransport));
}
И что самое интересное - оно работает!
До 64 КБт данных - одним плевком.
Это аватарка с эмблемой клуба спокойно поместятся (в jpeg формате).
Вот реализация приема на серверной части
Код:
void MyThread::readyRead()
{
// get the information
QByteArray Data = socket->readAll();
//emit socketClosed((qintptr)socketDescriptor);
// will write on server side window
qDebug() << socketDescriptor << " Data in: " << Data;
parsingData(Data);
socket->write(Data);
}
void MyThread::parsingData(QByteArray data)
{
int index;
buffer.append(data);
data.clear();
if(!preambleReceived)//если преамбула ещё не получена
{
index = buffer.indexOf("@HSL");//ищем преамбулу
if (index != -1) //найдена преамбула
{
preambleReceived = true;
buffer = buffer.mid(index);//удаляем данные до преамболы
if (buffer.size() > 0) parsingData(data);//рекурсивный вызов
}
}
else //приамбула уже получена
{
if (!headerRecieved)//заголовок ещё не получен
{
if (buffer.size() >= 14)//если все байты заголовок получен
{
headerRecieved = check_header();//проверяем контрольную сумму заголовка
if(headerRecieved)//если заголовок корректный
{
if (buffer.size() > 0) parsingData(data); //рекурсивный вызов
}
else //заголовок не корректный, ошибка
{
buffer = buffer.mid(14);//удаляем битый заголовок
preambleReceived = false; //начинаем искать следующий заголовок
if (buffer.size() > 0) parsingData(data);//рекурсивный вызов
}
}
}
else //корректный заголовок получен
{
qint16 data_len;
data_len = buffer.at(11);
data_len = data_len << 8;
data_len |= buffer.at(10);
if (buffer.size() >= (data_len+14))//все ли байты данных получены?
{ //все получены
QByteArray data_tmp;
quint8 checkSUM;
data_tmp = buffer.mid(14); //выдергиваем из пакета только прикрепленные данные
data_tmp = data_tmp.left(data_len);
checkSUM = calculateCheckSun(data_tmp);
if(checkSUM == buffer.at(12))//получен целый пакет, контрольная сумма совпадает
{
RX_Package = buffer.left(data_len+14);//готовим пакет для выдачи "наверх"
buffer = buffer.mid(data_len+14);
emit incomingPackage((int)socketDescriptor, RX_Package);//сигналим, что пакет получен
headerRecieved = false;
preambleReceived = false;
data.clear();
if(buffer.size()>0)//если буфер не пустой
{
parsingData(data); //рекурсивный вызов
}
}
else //ошибка, не совпадает контрольная сумма данных
{
buffer = buffer.mid(14);//удаляем из буфера заголовок
headerRecieved = false;
preambleReceived = false;
if(buffer.size()>0)//если буфер не пустой
{
parsingData(data); //рекурсивный вызов
}
}
int i;
i++;
}
else//ещё не все данные получены, дождемся следующей порции данных
{
}
}
}
}
bool MyThread::check_header()
{
quint8 sum;
sum=0;
for(int i=0;i< 14-1 ; i++)
{
sum = sum^buffer.at(i);
}
if (sum == buffer.at(13)) return true;
else return false;
}
quint8 MyThread::calculateCheckSun(QByteArray data)
{
quint8 sum;
sum=0;
for(int i=0;i<data.size() ; i++)
{
sum = sum^data.at(i);
}
return sum;
}