0
Answer

Image processing from the client through TCP socket failed

Jithin Jose

Jithin Jose

7y
267
1
I am developing an application for viewing client screen over TCP socket. my server application is in C# and the client application is in C++. I could send the image to the server without any error. At the server end, while converting buffer length I am getting a big number and this causes 'Overflow exception' while making image buffer with that size. Following are the code I have tried.
 
Server Code
 
  1. public static void StartListening()  
  2. {  
  3.     // Data buffer for incoming data.  
  4.     byte[] bytes = new Byte[1024];  
  5.   
  6.     // Establish the local endpoint for the socket.  
  7.     // The DNS name of the computer  
  8.     // running the listener is "host.contoso.com".  
  9.     IPHostEntry ipHostInfo = Dns.GetHostEntry("127.0.0.1");  
  10.     IPAddress ipAddress = ipHostInfo.AddressList[0];  
  11.     IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 11000);  
  12.   
  13.     // Create a TCP/IP socket.  
  14.     Socket listener = new Socket(AddressFamily.InterNetwork,  
  15.         SocketType.Stream, ProtocolType.Tcp);  
  16.   
  17.     // Bind the socket to the local endpoint and listen for incoming connections.  
  18.     try  
  19.     {  
  20.         listener.Bind(localEndPoint);  
  21.         listener.Listen(100);  
  22.   
  23.         while (true)  
  24.         {  
  25.             // Set the event to nonsignaled state.  
  26.             allDone.Reset();  
  27.   
  28.             // Start an asynchronous socket to listen for connections.  
  29.             Console.WriteLine("Waiting for a connection...");  
  30.             listener.BeginAccept(  
  31.                 new AsyncCallback(AcceptCallback),  
  32.                 listener);  
  33.   
  34.             // Wait until a connection is made before continuing.  
  35.             allDone.WaitOne();  
  36.         }  
  37.   
  38.     }  
  39.     catch (Exception e)  
  40.     {  
  41.         Console.WriteLine(e.ToString());  
  42.     }  
  43.   
  44.     Console.WriteLine("\nPress ENTER to continue...");  
  45.     Console.Read();  
  46.   
  47. }  
  48.   
  49. public static void AcceptCallback(IAsyncResult ar)  
  50. {  
  51.     // Signal the main thread to continue.  
  52.     allDone.Set();  
  53.   
  54.     // Get the socket that handles the client request.  
  55.     Socket listener = (Socket)ar.AsyncState;  
  56.     Socket handler = listener.EndAccept(ar);  
  57.   
  58.     // Create the state object.  
  59.     StateObject state = new StateObject();  
  60.     state.workSocket = handler;  
  61.     handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,  
  62.         new AsyncCallback(ReadHeaderCallback), state);  
  63. }  
  64.   
  65. public static void ReadHeaderCallback(IAsyncResult ar)  
  66. {  
  67.     // Retrieve the state object and the handler socket  
  68.     // from the asynchronous state object.  
  69.     StateObject state = (StateObject)ar.AsyncState;  
  70.     Socket handler = state.workSocket;  
  71.   
  72.     // Read data from the client socket.   
  73.     int bytesRead = handler.EndReceive(ar);  
  74.   
  75.     //we need to add error handler here...but later  
  76.     state.ImageSize = BitConverter.ToInt32(state.buffer, 0);  
  77.     _imageBuff = new byte[state.ImageSize];  
  78.     _totBytesRead = 0;  
  79.     handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,  
  80.        new AsyncCallback(ReadCallback), state);  
  81. }  
  82.   
  83. public static void ReadCallback(IAsyncResult ar)  
  84. {  
  85.     String content = String.Empty;  
  86.   
  87.     // Retrieve the state object and the handler socket  
  88.     // from the asynchronous state object.  
  89.     StateObject state = (StateObject)ar.AsyncState;  
  90.     Socket handler = state.workSocket;  
  91.   
  92.     // Read data from the client socket.   
  93.     int bytesRead = handler.EndReceive(ar);  
  94.   
  95.   
  96.     if (bytesRead > 0)  
  97.     {  
  98.         // There  might be more data, so store the data received so far.  
  99.         Buffer.BlockCopy(state.buffer, 0, _imageBuff, _totBytesRead, bytesRead);  
  100.   
  101.         _totBytesRead += bytesRead;  
  102.   
  103.         if (_totBytesRead < state.ImageSize)  
  104.         {  
  105.             // Not all data received. Get more.  
  106.             handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,  
  107.             new AsyncCallback(ReadCallback), state);  
  108.         }  
  109.         else  
  110.         {  
  111.             File.WriteAllBytes(@"c:\temp\incoming\untitled.bmp", _imageBuff);  
  112.         }  
  113.     }  
  114. }  
  115. public static int Main(String[] args)  
  116. {  
  117.     StartListening();  
  118.     return 0;  
  119. }  
Client Code:
 
  1. void SendScreen()  
  2. {  
  3. HDC hdcScreen;  
  4. HDC hdcWindow;  
  5. HDC hdcMemDC = NULL;  
  6. HBITMAP hbmScreen = NULL;  
  7. BITMAP bmpScreen;  
  8.   
  9. HWND hWnd = GetDesktopWindow();  
  10.   
  11. // Retrieve the handle to a display device context for the client   
  12. // area of the window.   
  13. hdcScreen = GetDC(NULL);  
  14. hdcWindow = GetDC(hWnd);  
  15.   
  16. // Create a compatible DC which is used in a BitBlt from the window DC  
  17. hdcMemDC = CreateCompatibleDC(hdcWindow);   
  18.   
  19. if(!hdcMemDC)  
  20. {  
  21.     //MessageBox(hWnd, L"CreateCompatibleDC has failed",L"Failed", MB_OK);  
  22.     goto done;  
  23. }  
  24.   
  25. // Get the client area for size calculation  
  26. RECT rcClient;  
  27. GetClientRect(hWnd,&rcClient);  
  28.   
  29. //This is the best stretch mode  
  30. SetStretchBltMode(hdcWindow,HALFTONE);  
  31.   
  32. //The source DC is the entire screen and the destination DC is the current   
  33. window (HWND)  
  34. if(!StretchBlt(hdcWindow,   
  35.            0,0,   
  36.            rcClient.right, rcClient.bottom,   
  37.            hdcScreen,   
  38.            0,0,  
  39.            GetSystemMetrics (SM_CXSCREEN),  
  40.            GetSystemMetrics (SM_CYSCREEN),  
  41.            SRCCOPY))  
  42.     {  
  43.     MessageBox(hWnd, "StretchBlt has failed","Failed", MB_OK);  
  44.     goto done;  
  45. }  
  46.   
  47. // Create a compatible bitmap from the Window DC  
  48. hbmScreen = CreateCompatibleBitmap(hdcWindow, rcClient.right-rcClient.left,   
  49. rcClient.bottom-rcClient.top);  
  50.   
  51. if(!hbmScreen)  
  52. {  
  53.     MessageBox(hWnd, "CreateCompatibleBitmap Failed","Failed", MB_OK);  
  54.     goto done;  
  55. }  
  56.   
  57. // Select the compatible bitmap into the compatible memory DC.  
  58. SelectObject(hdcMemDC,hbmScreen);  
  59.   
  60. // Bit block transfer into our compatible memory DC.  
  61. if(!BitBlt(hdcMemDC,   
  62.            0,0,   
  63.            rcClient.right-rcClient.left, rcClient.bottom-rcClient.top,   
  64.            hdcWindow,   
  65.            0,0,  
  66.            SRCCOPY))  
  67.    {  
  68.     MessageBox(hWnd, "BitBlt has failed""Failed", MB_OK);  
  69.     goto done;  
  70.    }  
  71.   
  72. // Get the BITMAP from the HBITMAP  
  73. GetObject(hbmScreen,sizeof(BITMAP),&bmpScreen);  
  74.   
  75. BITMAPFILEHEADER   bmfHeader;      
  76. BITMAPINFOHEADER   bi;  
  77.   
  78. bi.biSize = sizeof(BITMAPINFOHEADER);      
  79. bi.biWidth = bmpScreen.bmWidth;      
  80. bi.biHeight = bmpScreen.bmHeight;    
  81. bi.biPlanes = 1;      
  82. bi.biBitCount = 32;      
  83. bi.biCompression = BI_RGB;      
  84. bi.biSizeImage = 0;    
  85. bi.biXPelsPerMeter = 0;      
  86. bi.biYPelsPerMeter = 0;      
  87. bi.biClrUsed = 0;      
  88. bi.biClrImportant = 0;  
  89.   
  90. DWORD dwBmpSize = ((bmpScreen.bmWidth  bi.biBitCount + 31) / 32)  4 *   
  91. bmpScreen.bmHeight;  
  92. HANDLE hDIB = GlobalAlloc(GHND,dwBmpSize);   
  93. char lpbitmap = (char )GlobalLock(hDIB);      
  94. GetDIBits(hdcWindow, hbmScreen, 0,  
  95.     (UINT)bmpScreen.bmHeight,  
  96.     lpbitmap,  
  97.     (BITMAPINFO *)&bi, DIB_RGB_COLORS);  
  98. HANDLE hFile = CreateFile("capture.bmp",  
  99.     GENERIC_WRITE,  
  100.     0,  
  101.     NULL,  
  102.     CREATE_ALWAYS,  
  103.     FILE_ATTRIBUTE_NORMAL, NULL);     
  104.   
  105. // Add the size of the headers to the size of the bitmap to get the total file size  
  106. DWORD dwSizeofDIB = dwBmpSize + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);  
  107.   
  108. //Offset to where the actual bitmap bits start.  
  109. bmfHeader.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER);   
  110.   
  111. //Size of the file  
  112. bmfHeader.bfSize = dwSizeofDIB;   
  113.   
  114. //bfType must always be BM for Bitmaps  
  115. bmfHeader.bfType = 0x4D42; //BM      
  116.   
  117.   
  118. DWORD dwBytesWritten = 0;  
  119. WriteFile(hFile, (LPSTR)&bmfHeader, sizeof(BITMAPFILEHEADER), &dwBytesWritten, NULL);  
  120. WriteFile(hFile, (LPSTR)&bi, sizeof(BITMAPINFOHEADER), &dwBytesWritten, NULL);  
  121. WriteFile(hFile, (LPSTR)lpbitmap, dwBmpSize, &dwBytesWritten, NULL);  
  122. SendingToSocketBFH(bmfHeader);  
  123. SendingToSocketBIH(bi);  
  124. SendingToSocket(lpbitmap,dwBmpSize);  
  125.   
  126.   
  127. //Unlock and Free the DIB from the heap  
  128. GlobalUnlock(hDIB);      
  129. GlobalFree(hDIB);  
  130.   
  131. //Close the handle for the file that was created  
  132. CloseHandle(hFile);  
  133.   
  134. //Clean up  
  135. done:  
  136. DeleteObject(hbmScreen);  
  137. DeleteObject(hdcMemDC);  
  138. ReleaseDC(NULL,hdcScreen);  
  139. ReleaseDC(hWnd,hdcWindow);  
  140. }  
  141.   
  142. void SendingToSocketBFH(BITMAPFILEHEADER bfinfo)  
  143. {  
  144. DWORD dwErr=0;  
  145. int sent=0;  
  146. sent = Send((char*)&bfinfo,sizeof(bfinfo),0);  
  147. dwErr = GetLastError();  
  148. }  
  149.   
  150. void SendingToSocketBIH(BITMAPINFOHEADER binfo)  
  151. {  
  152. DWORD dwErr=0;  
  153. int sent=0;  
  154. sent = Send((char*)&binfo,sizeof(binfo),0);  
  155. dwErr = GetLastError();  
  156. }  
  157.   
  158. void SendingToSocket(char* cpBuff,int iLen)  
  159. {  
  160. DWORD dwErr=0;  
  161. int sent=0;  
  162. sent = Send(cpBuff,iLen,0);  
  163. dwErr = GetLastError();  
  164. }