Miałem to w swojej inżynierce tylko, że w QT. Ogólnie to było moje pierwsze spotkanie z gniazdami i było zdziwko. Jeśli 2 pakiety zostaną po sobie wysłane mogą zostać odczytane jako 1. Opracuj własną strukturę pakietu i funkcje go odczytującą. U mnie pakiety to było:
Rozmiar pakietu | separator (np. ";") | Dane. Wtedy dostając coś takiego:
5;abcde6;abcdef7l;
Wiedziałem, że zostały wysłane co najmniej 3 pakiety bo widzimy tu już zaczątek kolejnego. Moja funkcja działała na zasadzie:
1.Odczytaj kilka pierwszych bajtów pakietu (żeby poznać rozmiar)
2. Odczytaj rozmiar-już przeczytane bajty aby odczytać cały pakiet. Przykładowo jeśli rozmiar miałby maxymalnie 3 bajty to dla ciagu "5;abcde6;abcdef7"
Odczyta 5;a - ok. Pakiet będzie miał 5 bajtów. Odczytałem już 1 bajt z wiadomości (a). Teraz przeczytam 5-1 bajtów. Masz pierwszy pakiet itp
drugi krok to samo
3 krok - odczytałem 7; - ale nie ma żadnych bajtów w buforze więc zaczekam.
Proszę:
void Klient::wiadomoscDoSerwera(QByteArray wiadomosc)
{
int rozmiar = wiadomosc.size();
wiadomosc.insert(0,"$");
wiadomosc.insert(0, QString::number(rozmiar));
//porcjowanie
int beg=0;
int end=4000;
QString calosc(wiadomosc);
int wyslane=0;
while(beg<wiadomosc.size())
{
if(beg+end>wiadomosc.size())
end = wiadomosc.size()-beg;
wyslane+=socket->write(QByteArray(calosc.toStdString().substr(beg, end).c_str()));
// socket->flush();
QCoreApplication::processEvents();
QCoreApplication::processEvents();
// while(socket->bytesAvailable()==0);
// socket->waitForReadyRead();
//QByteArray smieci = socket->readLine();
beg+=4000;
}
//Debug::msgbox("Wyslane "+QString::number(wyslane));
}
Odbieranie:
void Serwer::obsluzWiadomosc()
{
// QTcpSocket* socket = server->
QTcpSocket* socket = static_cast<QTcpSocket*>(sender());
// socket->open(QIODevice::ReadWrite);
// Debug::pom();
static QByteArray wiadomosc;
static int rozmiar=0;
int liczbaDostepnychBajtow = socket->bytesAvailable();
while(socket->bytesAvailable())
{
if(wiadomosc=="")
{
wiadomosc = socket->read(10);
QList<QByteArray> wiadomosci = wiadomosc.split('$');
rozmiar = wiadomosci[0].toInt();
wiadomosc = wiadomosci[1];
}
while(wiadomosc.size()!=rozmiar)
{
liczbaDostepnychBajtow = socket->bytesAvailable();
if(liczbaDostepnychBajtow == 0)
break;
wiadomosc.append(socket->read(qMin((rozmiar-wiadomosc.size()), 4000)));
liczbaDostepnychBajtow = socket->bytesAvailable();
}
////PARSOWANIE
if(wiadomosc.size() == rozmiar)
{
QByteArray kopia(wiadomosc);
wiadomosc = "";
rozmiar =0;
if(QString(kopia).toStdString().substr(0, 3) == "dmc")
{
qDebug()<<"Serwer. Dostalem wiadomosc dmc: "<<kopia;
wyslijWszystkim(kopia);
}else
{
emit przyszlaWiadomosc(kopia, socket);
}
}
if(liczbaDostepnychBajtow == 0)
return;
}
}