通过TCP在C++客户端/ C#服务器之间传输文件

问题描述:

我目前正尝试通过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

您阅读文件大小,但我没有看到您发送文件大小的位置? –

变化:

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'首先发送文件大小然后文件内容。这可能是错误的,但值得尝试。 –