2012-12-10 37 views
5

是否有任何簡單的方法發送文件到服務器與文件名包括在服務器和客戶端的文件名是完全一樣的?如何通過QTCPSocket發送文件及其文件名?

這裏是我的代碼

發件人

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(); 

接收機

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(); 

回答

5
  1. 您可以創建自己的數據結構,將代表文件的內容和它的文件名,並將其轉換到QByteArray,反之亦然。

  2. 您可以發送兩個請求:第一個是文件名,第二個是數據。

+0

謝謝你的迴應Hank, 你的第一個建議對我來說有點複雜因爲我是C++和Qt的新手。你能給我一個示例代碼來將數據結構轉換爲QByteArray嗎? 關於您的第二個建議, 如何處理套接字數據,以便服務器可以識別套接字數據是否包含文件名或數據。 –

5

沒有真正簡單的方法。你必須創建你自己的協議。但是,該協議通常可以是非常非常簡單的協議。

在使用QString::toUtf8()

  • 寫入到插座的QByteArray的長度爲二進制INT
  • 寫入到套接字從QByteArray中包含該文件的字節

    1. 轉換QString的文件名寫入結束時,簡單的例子來的QByteArray名稱
    2. 向套接字寫入文件長度爲二進制int
    3. 向套接字寫入文件中的字節
    4. 關閉

    在讀取結束:

    1. 文件名的讀取整數告訴長度
    2. 閱讀很多字節從QByteArray中到QString的一個QByteArray中
    3. 轉換文件名中使用QString::fromUtf8()
    4. 讀取整數,告訴數據長度
    5. 保持讀取字節並寫入文件直到你得到了多少字節
    6. 關閉

    當寫入和讀出,如果你想在不同計算機之間進行溝通,你應該轉換成網絡字節順序寫入之前,和反讀取後爲主機字節順序。你也可以決定定義,你使用「x86字節順序」,並且任何人讀取不同CPU需要的數據進行轉換...

  • +0

    感謝您對hyde的迴應, 您的建議似乎非常有用。但作爲一個新手,我有一個問題。 如何處理傳入的套接字數據,以便我可以將數據放在該協議中的正確步驟。 (正如我們所知,在某些軟件包中發送的TCP寫入數據。) –

    +0

    TCP/IP是一種流協議,您可以寫入和讀取字節,而不是數據包。它還保證所有字節的順序和傳輸。所以你可以相信你會得到完全相同的順序完全相同的字節(或者你會得到錯誤和斷開連接)。這也是爲什麼你必須將自己的「數據包大小」寫入套接字的原因,因爲TCP/IP不會給你數據包的大小,只是字節流。 – hyde

    +0

    現在好了:) 謝謝你海德。 –