Remote monitoring of computers via Socket socket

xiaoxiao2021-03-06  214

I. Introduction

In engineering construction, the central main control unit and engineering site separation are often encountered, which requires engineering designers to and from the central computer room and engineering site, sometimes even in order to modify several data. Can solve it. It also does not have a good monitoring of the project site, which has brought great inconvenience to engineering construction and system maintenance. Nowadays, the technology of local area network is quite mature, and it is not difficult to build a local area network between the central computer room and the project site. Therefore, we can achieve communication between the computer through the Socket socket based on the physical architecture of the LAN, so that the maintenance personnel can monitor in real time without leaving the maintenance personnel, and control the computer far in the project site. Working status. This article briefly introduces the implementation of similar procedures.

Second, the general idea of ​​the Socket network program

The Windows Sockets specification defines a Microsoft Windows-based network programming interface that is derived from Berkeley Software Release (BSD) of Berkeley, University of Berkeley, Califlandia. It includes both familiar Berkeley Socket style routines, as well as a set of Windows unique extensions, allowing programmers to make network programmers using the original message drive mechanisms of Windows. One of the most common modes in such procedures is customer / server mode. In this framework, the client application requests service to the server application. Server applications typically listen to the Listen service request on a known address. That is, the server process process is sleeping until a customer issues a connection request to the server. When receiving the request, the server process "wakes up" to complete the corresponding activities of the customer request.

There are three types of sockets: stream socket, data settles, and original sockets, etc. Flow socket defines a reliable connection-oriented service that implements no errorless sequential data transmission; data report sets define a connectionless service, data is transmitted independently of each other. It is unordered, and does not guarantee reliability; the original socket allows direct access to protocols such as IP or ICMP, mainly for testing of new network protocols. Unconnected servers are generally transaction-oriented, a request for a response completed the interaction between the client and the service program. Request for connection server processing is often more complicated, not a request response to a request, and it is often a concurrent server. This article is the connection-oriented socket, the work process is as follows: The server starts first, build a socket by calling socket (), and then calls bind () to contact the socket and the local network address. Then call listen () to prepare the socket, and specify the length of its request queue, then call accept () to receive the connection. Customers can call Connect () and servers to establish a connection after establishing a socket. Once the connection is established, the client and server can send and receive data by calling read () and write (). Finally, after the data is transmitted, the two parties call close () shut down socket. The main process timing can be represented by Figure 1:

Third, the server-side programming implementation Since our purpose is to monitor the remote server side by the client located in the central computer room, the server must be prior to the client based on the way the connection socket application is described above. Run. So according to actual needs, we should let the server program can start from starting. There are three ways: add code in autoexec.bat; add a start path to the run.ini's Run (add key value in the registry. This article uses the latter method, by adding a key value to the Software // Microsoft // Windows // CurrentVersion // RUN of the registry, or adding a key value to the RunServer: ...... // Set the path of the registry to be added lpctstr rgspath = "software // microsoft // windows // currentversion //r"; ... // Get system path getSystemDirectory (syspath, size); getModuleFileName (Null, CurrentPath, Size); ... // copy the service program from the current location into the system directory FileCurrentName = CurrentPath; filenewname = lstrcat (syspath, "// system_server.exe"); ret= copyfile (filecurrentname, filenewname, true); ...... // open key ret = RegOpenKeyEx (HKEY_LOCAL_MACHINE, Rgspath, 0, KEY_WRITE, & hKEY); if (ret = ERROR_SUCCESS!) {RegCloseKey (hKEY); return FALSE;} // set the key ret = RegSetValueEx (hKEY, "System_Server ", NULL, TYPE, (const unsigned char *) filenewname, size); if (ret! = Error_success) {regclosekey (hkey); return false;} // Close key value regcloseKey (HKEY); after registration, Self-start. The following focus on this article: Programming the socket, first initializing the socket port, and creates a socket by calling socket () under the premise of initialization, then call Bind () to connect the socket and local network address Contacts, then call listen () to make the socket ready to listen, and specify its length of request queue. Where the listen () function is mainly used to build a socket socket to listen to the connection, and only support the socket, which is the SOCKET of SOCK_STREAM. This socket is set to "passive" mode, responsible for responding, and hangs up the join connection from the process. This function is typically used to have multiple coupled servers at the same time: if a join request arrives and the queue is full, the client will receive a WSAECONNREFUSED error. When there is no descriptor available, Listen () will try to put the function reasonably. It will accept the join until the queue is empty. If the descriptor is available, the later pair listen () or accept () call will populate the queue to the current or most recent cumulatory number (the current or mostlog ''), maybe, continue to listen Join.

The following are the main part of code that: ...... wMajorVersion = MAJOR_VERSION; wMinorVersion = MINOR_VERSION; wVersionReqd = MAKEWORD (wMajorVersion, wMinorVersion); ...... Status = WSAStartup (wVersionReqd, & lpmyWSAData); if (Status = 0!) Return FALSE; ...... // create the socket ServerSock = socket (AF_INET, SOCK_STREAM, 0); if (ServerSock == INVALID_SOCKET) return FALSE; dstserver_addr.sin_family = PF_INET; dstserver_addr.sin_port = htons (7016); dstserver_addr.sin_addr.s_addr = INADDR_ANY ; // bind status = bind (STRUCT SOCKADDR FAR *) & dstserver_addr, sizeof (dstserver_addr)); if (status! = 0) Return False; // Listen Status = Listen (Serversock, 1); if (Status! = 0) Return False; Next, you need to call accept () to receive the connection. Customers can call Connect () and servers to establish a connection after establishing a socket. Its function is: Socket Pascal Far Accept (Socket S, Struct SockAddr Far * Addr, Int Far * Addrlen); this routine removes the first join from the coupling queue hang on S, with the same characteristics as S Create a new Socket and return the new socket handle. If there is no hang in the queue, and the socket is not indicated by non-blocking, the Accept () blocks the caller until there is a join. Socket (Accept Socket) that has been accepted is not applied to accept more links. The parameter addr is a returned parameter that is filled in the connection entity address of the communication layer. The strict format of the address parameter addr is determined by the address family of communicating. Addrlen is a return parameter value; this value contains the buffer space length pointed to the ADDR before calling; the actual length of the return address is included when the call is returned. // ACCEPT int len ​​= sizeof (dstserver_addr); NewSock = accept (ServerSock, (struct sockaddr far *) & dstserver_addr, & len); if (NewSock <0) {closesocket (ServerSock); return FALSE;} // Get the screen size SysWidth = GetSystemMetrics; sysHeight = getSystemMetrics (SM_CYSCREEN); ... Connection Once the client and server can send and receive data by calling read () and Write (). Finally, after the data transfer is completed, the Close () shuts down the socket.

The following functions are responsible for sending the current screen state to the client through the SEND function in the form of data to implement remote monitoring of the computer-side computer: ... // send falg falg = us_flag; send (newsock, (char *) & Falg, sizeof (falg) 1, MSG_OOB); // Get Message Length = Recv (Newsock, (Char *) & IMSG, SIZEOF (IMSG) 1, 0); if (Length <0) {// Close sock closesocket (NewSock); closesocket (ServerSock); return FALSE;} // GetMessageData if (iMsg <4500) {send (NewSock, (char *) & SysWidth, sizeof (SysWidth) 1, MSG_OOB); send (NewSock, ( Char *) & sysheight, sizeof (sysheight) 1, msg_oob);} Switch (IMSG) {copy us_desktopbit: // Send current screen image sendDesktop (); Break; ...} where the SendDesktop () function is responsible for saving the screen into the screen Bitmap, then send it to the form of data by the send () function, this part involves more bitmap operation, which is more cumbersome, because this paper is not here, only the key code is taken as a function function. Choose the following: void sendDesktop () {... // Create a desktop device environment handle HDCMY = Createdc ("Display", NULL, NULL, NULL); hbufferdc = createCompatibleDC (HDCMY); // Create a bitmap hbit = createcomPatibleBitmap (HDCMY, bitWidth, BitHeight); hOldBitmap = (HBITMAP) SelectObject (hbufferdc, hBit); StretchBlt (hbufferdc, 0, 0, bitWidth, BitHeight, hdcmy, 0, 0, SysWidth, SysHeight, SRCCOPY); hBit = (HBITMAP) SelectOb JECT (HBufferDC, HoldbitMap); ... // ddbtodib hpal = (hpalette) getStockObject (Default_palette); // Get bitmap information getObject (Bitmap, sizeof (bm), (lpstr) & bm); // Initialization bitmap information header Bi.bisize = sizeof (BitmapInfoHeader); bi.biwidth = bm.bmwidth; bi.biheight = bm.bmHeight; bi.Biplanes = 1; //bi.biBitcount = bm.bmplanes * bm.bmbitspixel; bi.biBitcount = 4 Bi.Bicompression = Bi_RGB; bi.bisizeImage = 0; bi.biypelspermeter = 0; bi.biypelspermeter = 0; bi.bi.bi.bi.bi.bi.bi.bi.bi.bi.bi.bi.bi.bi.bi.bi.bi.bi.bi.bi.bi.bi.bi.bi.bi.bi.bi.bi.bi.bi.bi.bi.bi.bi.bi.bi.bi.bi.bi.bi.bi.bi.bi.bi.bi.bi.bi.bi.bi.bi.bi.bi.Bi.BiRimportant = 0; ... lpbi = (lpbitmapinfoHeader) HDIB; * lpbi = bi ;

GetDibits (HDC, Bitmap, 0L, (DWORD) BI.BIHEIGHT, (LPBYTE) NULL, (LPBITMAPINFO) LPBI, (DWORD) DIB_RGB_COLORS; BI = * LPBI; IF (bi.bisizeImage == 0) bi.bisizeImage = ((bi.biwidth * bi.biBitcount) 31) & ~ 31) / 8) * bi.biheight; dwlen = bi.bisizeImage; if (HDIB, DWLEN, GMEM_MOVEABLE) HDIB = Handle; ...... lpbi = (LPBITMAPINFOHEADER) hDib; BOOL bgotbits = GetDIBits (hdc, bitmap, 0L, (DWORD) bi.biHeight, (LPBYTE) lpbi (bi.biSize ncolors * sizeof (RGBQUAD)), (LPBITMAPINFO) lpbi, ( DWORD) DIB_RGB_COLORS; SelectPalette (HDC, HPAL, FALSE); ... Send (Newsock, (Char *) & Bitsize, SizeOf (Bitsize) 1, MSG_OOB); Recv (Newsock, (Char *) & Bitmsg, Sizeof (Bitmsg) 1,0); PLMAGEPOINT = (lpbyte) HDIB; for (Word i = 0; i

Note If the address field of the name structure is all 0, Connect () will return to errors WSAEADDRNOTAVAIL. For streaming Sockets, the active connection to an external host that uses the name of the name (an address of the socket name). When the call is successfully completed, the Socket is ready to send / receive data.

The following is some of the main code of the timer message response function: ... ClientSock = Socket (AF_INET, SOCK_STREAM, 0); if (ClientSock <0) Return False; // Established Connection Client.sin_Family = PF_INET; Client.sin_Port = Htons 7016); client.sin_addr.s_addr = inet_addr (client_address); ...... msgsock = connect (clientSock, (struct sockaddr *) & client, sizeof (client));! if (msgsock = 0) return FALSE; ...... // get Screen size getWindowRect (hwnd, & rece); bitwidth = Rect.right - Rect.Left; BitHHHH = Rect.bottom - Rect.top; Recv (Clientsock, (Char *) & flag, sizeof (flag) 1,0); if (Flag == US_FLAG) {mouseEventflag = false; // Send message MSG = US_Desktopbit; Send (Clientsock, (Char *) & MSG, SIZEOF (MSG) 1, MSG_OOB); // Send Bit Height and Weidth Send (Clientsock, (Char *) & Bitwidth, Sizeof (Bitwidth) 1, MSG_OOB; Send (Clientsock, (Char *) & BitHETIGHT, SIZEOF (BitHHHEIGHT) 1, MSG_OOB); // Receive Data getDesktopbit (hwnd); mouseEventflag = true; // Close the socket, release the data clossoSocket (ClientSock); here the data from the server is completed by calling getDesktopbit (), making the data from the remote computer in the local client in the local client: ... // Get Bit Size Recv (Clientsock, (Char *) & Bitsize, SizeOf (Bitsize) 1,0); s End (clientsock, (charg) & flag, sizeof (flag) 1, msg_oob); // Lock memory HDIB = GlobalAlloc (gmem_moveable, bitsize); p = (lpbyte) Globalock (HDIB); p2 = p; for (Word i = 0; i

转载请注明原文地址:https://www.9cbs.com/read-128679.html

New Post(0)