2012-12-10 14 views
5

Czy istnieje prosty sposób wysłania pliku na serwer z zawartą nazwą pliku, aby nazwa pliku na serwerze i kliencie była dokładnie taka sama?Jak wysłać plik wraz z jego nazwą przez QTCPSocket?

Oto mój kod

Sender

QString path = QApplication::applicationDirPath()+"/belajardansa.bmp"; 
QFile inputFile(path); 
QByteArray read ; 
inputFile.open(QIODevice::ReadOnly); 
while(1) 
{ 
    read.clear(); 
    read = inputFile.read(32768*8); 
    qDebug() << "Read : " << read.size(); 
    if(read.size()==0) 
     break; 
    qDebug() << "Written : " << socket->write(read); 
    socket->waitForBytesWritten(); 
    read.clear(); 
} 
inputFile.close(); 

Odbiornik

QTcpSocket* socket = static_cast<QTcpSocket*>(sender()); 
QBuffer* buffer = buffers.value(socket); 

QByteArray read = socket->read(socket->bytesAvailable()); 
qDebug() << "Read : " << read.size(); 

QFile file( ???); // what should I put in the bracket??? 
if(!(file.open(QIODevice::Append))) 
{ 
    qDebug("File cannot be opened."); 
    exit(0); 
} 
file.write(read); 
file.close(); 

Odpowiedz

5
  1. Można utworzyć własną strukturę danych, która będzie reprezentować zawartość pliku i jego nazwę pliku i przekształcić ją do QByteArray i na odwrót.

  2. Możesz wysłać dwie prośby: pierwszą z nazwą pliku i drugą z danymi.

+0

Dziękujemy za odpowiedź Hank, Twoja pierwsza sugestia jest dla mnie nieco skomplikowana ponieważ jestem nowicjuszem w C++ i Qt. Czy możesz podać przykładowy kod do konwersji struktury danych na QByteArray? o drugiej sugestii, Sposób rozmieszczenia danych gniazda, aby serwer mógł rozpoznać, czy dane gniazda zawierają nazwę pliku lub dane. –

5

Nie ma naprawdę prostego sposobu. Musisz stworzyć własny protokół. Jednak protokół ten może często być bardzo bardzo prostym protokołem.

na pisaniu koniec, prosty przykład

  1. Convert QString pliku do QByteArray użyciu QString::toUtf8()
  2. zapisać do gniazda długość QByteArray jako binarne int
  3. zapisać do gniazda w bajtach od QByteArray zawierający plik nazwa
  4. Zapisuj w gnieździe długość pliku jako binarną int
  5. Zapisz do gniazda bajty z pliku
  6. Close

na czytanie końca:

  1. Czytaj długość całkowita wymowne nazwy pliku
  2. Czytaj że wiele bajtów do QByteArray
  3. nazwy pliku przekonwertować z QByteArray do QString użyciu QString::fromUtf8()
  4. Odczytaj liczbę całkowitą określającą długość danych
  5. Kontynuuj czytanie bajtów i zapisuj do pliku dopóki nie dostał, że wiele bajtów
  6. Zamknij

Podczas pisania i czytania, jeśli chcesz komunikować się pomiędzy różnymi komputerami, należy przekonwertować do sieciowej kolejności bajtów przed zapisem oraz z powrotem do hosta kolejność bajtów po przeczytaniu. Możesz również zdecydować, aby użyć "zamawiania bajtów x86", a każdy odczytujący dane z różnymi procesorami musi przekonwertować ...

+0

dziękuję za odpowiedź hyde, Twoja sugestia wydaje się bardzo przydatna. Ale jest jeden problem dla mnie jako początkującego. W jaki sposób obsłużyć przychodzące dane gniazd, aby można było umieścić dane w odpowiednim kroku w tym protokole. (Jak wiemy, w zapisanych danych TCP przesyłanych w niektórych pakietach.) –

+0

TCP/IP jest protokołem strumieniowym, piszesz i czytasz bajty, a nie pakiety. Gwarantuje również porządek i transmisję wszystkich bajtów. Możesz więc ufać, że otrzymasz dokładnie te same bajty w tej samej kolejności (lub pojawi się błąd i rozłączenie). Właśnie dlatego musisz pisać własne "rozmiary pakietów" do gniazda, ponieważ protokół TCP/IP nie daje pakietów o rozmiarze, tylko strumień bajtów. – hyde

+0

ok, teraz to zrobiłem :) Dziękuję, hyde. –