2017-04-04 114 views
1

我目前正嘗試通過TCP在C++客戶端和C#服務器之間發送jpeg圖片流。 我在C++端使用transmitFile函數,但我不知道我是否在C#端正確處理它。 我沒有得到運行時錯誤,但圖片沒有顯示,所以我想我錯過了一些東西。通過TCP在C++客戶端/ C#服務器之間傳輸文件

編輯:更新後的代碼,我收到正在做一個計算器檔案大小...

C++代碼(客戶端:發送圖片)

void TCPclient::sendPicture(LPCWSTR filename, std::string filename_str) 
{ 
    HANDLE hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL); 
    //Send file size 
    send(sock, (const char*)GetSize(filename_str), sizeof(int), 0); 
    LogManager::log(std::to_string(GetSize(filename_str))); 
    //Send file 
    TransmitFile(sock, hFile, GetFileSize(hFile, NULL), 1024, NULL, NULL, TF_USE_KERNEL_APC | TF_WRITE_BEHIND); 
    CloseHandle(hFile); 
} 

int TCPclient::GetSize(std::string filename) 
{ 
    struct stat stat_buf; 
    int rc = stat(filename.c_str(), &stat_buf); 
    return rc == 0 ? stat_buf.st_size : -1; 
} 

C#代碼(服務器:接收圖像和顯示它)

while (true) 
     { 
      try 
      { 
       using (MemoryStream stream = new MemoryStream(ReceiveVarData(clientSock))) 
       { 
        stream.Position = 0; 
        Image image = Image.FromStream(stream); 
        if (image != null) 
         pictureBox1.Image = image; 
       } 
      } 
      catch (Exception ex) 
      { 
       Console.WriteLine(ex.ToString()); 
      } 
     } 

    public static byte[] ReceiveVarData(Socket s) 
    { 
     Console.WriteLine("Receiving data ..."); 
     int offset = 0; 
     int recv; 
     Console.WriteLine("Receiving data size ..."); 
     byte[] datasize = new byte[4]; 
     s.Receive(datasize); 
     int size = BitConverter.ToInt32(datasize, 0); 
     Console.WriteLine("Data size " + size); 
     byte[] data = new byte[size]; 
     while (offset < size) 
     { 
      Console.WriteLine("Downloading " + (offset/size)*100.0 + "%"); 
      recv = s.Receive(data, offset, 1024, SocketFlags.None); 
      if (recv == 0) 
      { 
       data = null; 
       break; 
      } 
      offset += recv; 
     } 
     return data; 
    } 
+0

您閱讀文件大小,但我沒有看到您發送文件大小的位置? –

回答

1

變化:

using (Image image = Image.FromStream(new MemoryStream(ReceiveVarData(clientSock)))) 
{ 
    if (image != null) 
     pictureBox1.Image = image; 
} 

要這樣:

using (MemoryStream stream = new MemoryStream(ReceiveVarData(clientSock))) 
{ 
    stream.Position = 0; 
    Image image = Image.FromStream(stream); 
    if (image != null) 
     pictureBox1.Image = image; 
} 

你創建後處置你的Image客體的權利。
當用數據緩衝區實例化MemoryStream(從我記憶中)將它的位置設置到該流的末尾,因此您必須將MemoryStream.Position設置回到開頭。

+0

處理MemoryStream是一個非常討厭的錯誤。不幸的是,它不會經常導致異常。 –

+0

我已經更新了代碼,在嘗試讀取c#端的文件大小時遇到​​了stackoverflow錯誤.... – Germain

+0

@ Germain67請在不發送文件大小的情況下嘗試一致。從我記得'TransmitFile'首先發送文件大小然後文件內容。這可能是錯誤的,但值得嘗試。 –

相關問題