C++ Win32Api GUI, I Am trying to display received screenshots on server from client. I am trying to create a Remote Desktop Viewer. Client is capturing screenshots and then sending them to the server, where i am trying to receive and display to a window, but there are is a problem on which i am stuck at maybe a week. It is throwing std::bad_alloc when i received the image and try to add to memory on SERVER.(the screenshots are in jpeg format). Sometimes it throws std::bad_alloc instantly, but sometimes after received a few images.
Server.cpp {window procedure, the bad_alloc error is in WM_PAINT}:
case WM_PAINT:
{
SOCKET selectedSocket = clientSockets[itemIndex];
Sleep(1000 / 15);
ULONGLONG bufferLenNetworkOrder = 0;
int bytesReceived = 0;
int rerr = 0;
const int MAX_BYTES = 100000;
while (bytesReceived < sizeof(bufferLenNetworkOrder)) {
rerr = recv(selectedSocket, (char*)&bufferLenNetworkOrder + bytesReceived, sizeof(bufferLenNetworkOrder) - bytesReceived, 0);
bytesReceived += rerr;
}
int bufferLen = ntohll(bufferLenNetworkOrder);
imageBuffer.reset(new char[bufferLen]);
bytesReceived = 0;
while (bytesReceived < bufferLen && bufferLen < MAX_BYTES) {
MessageBoxA(NULL, std::to_string(bufferLen - bytesReceived).c_str(), "CHECK", MB_OK);
rerr = recv(selectedSocket, imageBuffer.get() + bytesReceived, bufferLen - bytesReceived, 0);
if (rerr > 0 && rerr <= bufferLen - bytesReceived) {
bytesReceived += rerr;
}
else {
MessageBoxA(NULL, "ERROR", "CHECK", MB_OK);
return {};
}
}
if (bufferLen > MAX_BYTES)
{
return {};
}
HGLOBAL hGlobal = GlobalAlloc(GHND, bufferLen);
void* pData = GlobalLock(hGlobal);
memcpy(pData, imageBuffer.get(), bufferLen);
GlobalUnlock(hGlobal);
IStream* pStream = NULL;
CreateStreamOnHGlobal(hGlobal, TRUE, &pStream);
Gdiplus::Bitmap bitmap(pStream);
Gdiplus::Status status = bitmap.GetLastStatus();
PAINTSTRUCT ps;
HDC hdc = BeginPaint(Chwnd, &ps);
int imgWidth = bitmap.GetWidth();
int imgHeight = bitmap.GetHeight();
Gdiplus::Graphics graphics(hdc);
RECT clientRect;
GetClientRect(Chwnd, &clientRect);
graphics.DrawImage(&bitmap, 0, 0, imgWidth, imgHeight);
GlobalFree(hGlobal);
pStream->Release();
imageBuffer.reset(new char[bufferLen]);
EndPaint(Chwnd, &ps);
break;
}
I fixed it by checking if the bufferLen is not zero or less than zero in a do-while loop. Big thanks to drescherjm.