通过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;
}
变化:
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
设置回到开头。
处理MemoryStream是一个非常讨厌的错误。不幸的是,它不会经常导致异常。 –
我已经更新了代码,在尝试读取c#端的文件大小时遇到了stackoverflow错误.... – Germain
@ Germain67请在不发送文件大小的情况下尝试一致。从我记得'TransmitFile'首先发送文件大小然后文件内容。这可能是错误的,但值得尝试。 –
您阅读文件大小,但我没有看到您发送文件大小的位置? –