Отправка данных Bitmap через winsock? Winapi

Я пытаюсь отправить скриншот рабочего стола через winsock.

Таким образом, есть четыре задачи:

Save bitmap to buffer
Write data across wire using a socket
Read data from wire using a socket
Load a bitmap from a buffer

Я сохранил растровое изображение в массив символов, используя GetDIBits. Запись данных на сервер я сделал, но есть вопросы. Для записи данных с сервера на клиент мне нужно использовать только 1 вызов recv() (я использую TCP) или мне нужно разделить его на несколько частей? Я читал, что TCP — это концепция потока, и что мне не нужно беспокоиться о пакетах, потому что для меня это абстрагировано?

Как мне загрузить информацию из GetDIBits в растровое изображение и отобразить ее в главном окне?

Я предполагаю, что мне нужно использовать SetDIBits, но в каких контекстах устройства я использую?

Скриншот сервера находится здесь:

 HDC handle_ScreenDC = GetDC(NULL);
HDC handle_MemoryDC = CreateCompatibleDC(handle_ScreenDC);
BITMAP bitmap;


int x = GetDeviceCaps(handle_ScreenDC, HORZRES);
int y = GetDeviceCaps(handle_ScreenDC, VERTRES);

HBITMAP handle_Bitmap = CreateCompatibleBitmap(handle_ScreenDC, x, y);
SelectObject(handle_MemoryDC, handle_Bitmap);

BitBlt(handle_MemoryDC, 0, 0, x, y, handle_ScreenDC, 0, 0, SRCCOPY);

GetObject(handle_Bitmap, sizeof(BITMAP), &bitmap);

BITMAPFILEHEADER bmfHeader;
BITMAPINFOHEADER bi;

bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = bitmap.bmWidth;
bi.biHeight = bitmap.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = 16;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
//std::cout<< bitmap.bmWidth;
DWORD dwBmpSize =((bitmap.bmWidth * bi.biBitCount + 5) / 32) * 4 * bitmap.bmHeight;
//int i = bitmap.bmWidth;
//DWORD dwBmpSize = 99;

HANDLE hDIB = GlobalAlloc(GHND, dwBmpSize);

char* bufptr = (char *)GlobalLock(hDIB);

GetDIBits(handle_ScreenDC, handle_Bitmap, 0, (UINT)bitmap.bmHeight, bufptr, (BITMAPINFO *)&bi, DIB_RGB_COLORS);


send(clientsock, bufptr , GlobalSize((char *)GlobalLock(hDIB)), 0);
/*Do i need to packetize/split it up? Or 1 send() is good for the matching Recv on the client?*/
/*I am assuming i must send bi structure over winsock also correct?*/

И принимающий клиентский код:

        case WM_PAINT:{

        //Im a Gdi beginner so I dont have a clue what im doing here as far as blitting the recved bits, this is just some stuff i tried myself before asking for help

        PAINTSTRUCT paintstruct;

        HDC handle_WindowDC = BeginPaint(hwnd, &paintstruct);

        handle_MemoryDC = CreateCompatibleDC(handle_WindowDC);


        handle_Bitmap = CreateCompatibleBitmap(handle_WindowDC, 640, 360);


         std::cout << SetDIBits(handle_MemoryDC, handle_Bitmap, 0, bi.biHeight, buffer, (BITMAPINFO *)&bi, DIB_RGB_COLORS);

        SelectObject(handle_MemoryDC, handle_Bitmap);

        StretchBlt(handle_WindowDC, 50, 50, 640, 360, handle_MemoryDC, 0, 0, x, y, SRCCOPY);


        EndPaint(hwnd, &paintstruct);

    }

person Kelvin    schedule 03.05.2013    source источник


Ответы (1)


Сокеты имеют ограниченный размер буфера на обоих концах, обычно около 4000 байт. Таким образом, если вы сбрасываете большой блок данных (например, полный снимок экрана) за один вызов неблокирующей отправки, вы, скорее всего, получите ошибки, и вам нужно будет управлять своими собственными буферами, вызывая несколько отправок. Однако, если вы используете неблокирующий сокет, все должно быть в порядке, так как send() будет просто блокироваться до тех пор, пока не будут отправлены все данные.

На принимающей стороне ситуация аналогична — блокирующий прием может просто ждать, пока не будет получен полный размер данных, который вы запрашивали, но неблокирующий прием вернется с любыми данными, доступными в это время, что приведет к в фильтрации данных по битам, и вам нужно будет повторно собрать данные из нескольких вызовов recv().

Я слышал о проблемах с отправкой действительно больших блоков данных за одно обращение, поэтому, если вы отправляете 5 мегабайт данных за одно обращение, имейте в виду, что могут возникнуть и другие проблемы.

person user1961169    schedule 21.06.2013