赞
踩
VNC具体用途,不用过多介绍了。这里只简单写一个获取服务器端画面的示例:
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- #include <cstdlib>
- #include <unistd.h>
- #include <rfb/rfbclient.h>
- #include <rfb/rfb.h>
- #include <png.h>
-
- void saveScreenshot(rfbClient* client, const char* filename) {
- std::cout << "Entering saveScreenshot function..." << std::endl;
-
- int width = client->width;
- int height = client->height;
- std::cout << "Dimensions: " << width << "x" << height << std::endl;
-
- FILE *fp = fopen(filename, "wb");
- if (!fp) {
- std::cerr << "Failed to open file for writing!" << std::endl;
- return;
- }
-
- png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
- png_infop info_ptr = png_create_info_struct(png_ptr);
- std::cout << "PNG structures initialized..." << std::endl;
-
- png_init_io(png_ptr, fp);
- png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB,
- PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
-
- png_byte** rows = (png_byte**)malloc(height * sizeof(png_byte*));
-
- std::cout << "Processing pixels..." << std::endl;
- for (int y = 0; y < height; y++) {
- rows[y] = (png_byte*)malloc(3 * width * sizeof(png_byte));
- for (int x = 0; x < width; x++) {
- uint16_t pixel = ((uint16_t*)client->frameBuffer)[y * width + x];
-
- uint8_t r = (pixel >> 10) & 0x1F; // 5 bits red
- uint8_t g = (pixel >> 5) & 0x1F; // 5 bits green
- uint8_t b = pixel & 0x1F; // 5 bits blue
-
- // Convert from 5 bits to 8 bits
- rows[y][x*3] = (r << 3) | (r >> 2);
- rows[y][x*3+1] = (g << 3) | (g >> 2);
- rows[y][x*3+2] = (b << 3) | (b >> 2);
- }
- }
-
- std::cout << "Writing PNG..." << std::endl;
- png_set_rows(png_ptr, info_ptr, rows);
- png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
-
- for (int y = 0; y < height; y++) {
- free(rows[y]);
- }
- free(rows);
- png_destroy_write_struct(&png_ptr, &info_ptr);
- fclose(fp);
-
- std::cout << "Exiting saveScreenshot function..." << std::endl;
- }
-
- rfbBool resize(rfbClient* client) {
- int width = client->width;
- int height = client->height;
- std::cout << "Resized to " << width << "x" << height << std::endl;
- client->frameBuffer = (uint8_t*)realloc(client->frameBuffer, width * height * client->format.bitsPerPixel / 8);
- return TRUE;
- }
-
- char* get_password(rfbClient* client) {
- return strdup("Ls1020..");
- }
-
- bool framebufferUpdated = false;
- static void frameBufferUpdateCallback(rfbClient* client, int x, int y, int w, int h) {
- static time_t t=0,t1;
- FILE* f;
- int i,j;
- rfbPixelFormat* pf=&client->format;
- int bpp=pf->bitsPerPixel/8;
- int row_stride=client->width*bpp;
-
- t1=time(NULL);
- if(t1-t>2)
- t=t1;
- else
- return;
-
- if(bpp!=4 && bpp!=2) {
- rfbClientLog("bpp = %d (!=4)\n",bpp);
- return;
- }
-
- f=fopen("framebuffer.ppm","wb");
- if(!f) {
- rfbClientErr("Could not open framebuffer.ppm\n");
- return;
- }
-
- fprintf(f,"P6\n# %s\n%d %d\n255\n",client->desktopName,client->width,client->height);
- for(j=0;j<client->height*row_stride;j+=row_stride)
- for(i=0;i<client->width*bpp;i+=bpp) {
- unsigned char* p=client->frameBuffer+j+i;
- unsigned int v;
- if(bpp==4)
- v=*(unsigned int*)p;
- else if(bpp==2)
- v=*(unsigned short*)p;
- else
- v=*(unsigned char*)p;
- fputc((v>>pf->redShift)*256/(pf->redMax+1),f);
- fputc((v>>pf->greenShift)*256/(pf->greenMax+1),f);
- fputc((v>>pf->blueShift)*256/(pf->blueMax+1),f);
- }
- fclose(f);
-
- framebufferUpdated = true;
- }
-
- int main(int argc, char *argv[]){
- rfbClient* client = rfbGetClient(8, 3, 4);
- client->MallocFrameBuffer = resize;
- client->GetPassword = get_password;
- client->serverHost = strdup("42.48.206.82");
- client->serverPort = 5901;
- client->GotFrameBufferUpdate = frameBufferUpdateCallback;
-
- if (!rfbInitClient(client, nullptr, nullptr)) {
- std::cerr << "Failed to initialize the client!" << std::endl;
- return 1;
- }
-
- // Request a full framebuffer update from the server
- std::cout << "Requesting framebuffer update..." << std::endl;
- SendFramebufferUpdateRequest(client, 0, 0, client->width, client->height, FALSE);
-
- std::cout << "Taking a screenshot..." << std::endl;
- time_t t = time(NULL);
- while (time(NULL)-t<50 && !framebufferUpdated) {
- int n = WaitForMessage(client,50);
- if(n < 0){
- // client->socket==-1
- break;
- }
-
- if (n==0){
- // no message from server
- }
-
- if(n){
- // handle message from server
- if(!HandleRFBServerMessage(client))
- break;
- }
- }
-
- if (framebufferUpdated){
- saveScreenshot(client, "screenshot.png");
- }
-
- rfbClientCleanup(client);
- return 0;
- }
如果需要实时更新服务器端画面,while循环就可以了。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。