Reputation: 718
I'm currently trying to send a stream of jpeg pictures between a c++ client and a C# server over TCP. I'm using the transmitFile function on C++ side but I don't know if I'm handling it properly on C#-side. I don't get runtime errors but the picture is not displayed, so I guess I'm missing something.
EDIT : Updated code, the fileSize I'm receiving is doing a stackOverflow...
C++ code (Client : sending picture)
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# code (Server : receiving the picture and displaying it)
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;
}
Upvotes: 1
Views: 871
Reputation: 5940
Change :
using (Image image = Image.FromStream(new MemoryStream(ReceiveVarData(clientSock))))
{
if (image != null)
pictureBox1.Image = image;
}
To this :
using ( MemoryStream stream = new MemoryStream(ReceiveVarData(clientSock)) )
{
stream.Position = 0;
Image image = Image.FromStream(stream);
if ( image != null )
pictureBox1.Image = image;
}
You're disposing your Image
object right after creating it.
When instantiating MemoryStream
with data buffer ( from what i remember ) will set it's position to the end of that stream so you have to set MemoryStream.Position
back to the beginning.
Upvotes: 2