Design a proxy server program with Delphi

zhaozj2021-02-11  171

Use the Delphi Design Proxy Server Program from "Tianji Network Learning Center" (Text / Wan Xue Yong) to develop serial communication software with Delphi: First, use Windows communication API functions, the other is the use of Microsoft MSCOMM controls . Using the API to write serial communication programs more complicated, you need to master a large number of communication knowledge, and the advantage is that the function is more powerful, more widely applied, more suitable for more complex low-level communication programs. The use of MSCOMM controls is relatively simple, which has a wealth of attributes and events closely related to serial port communication, providing various operations for serial ports. I. Main attributes and events of MSCOMM controls (1) CommPort: Set or return serial port numbers, default is 1. (2) Setting: Set or return serial communication parameters, format is "baud rate, parity bit, data bit, stop bit". For example: mscomm1.setting: = '9600, n, 8, 1' (3) Portopen: Open or close the serial port, format is: mscomm1.portopen: = {True | false} (4) Inbuffersize: Set or return to receive The buffer size, the default is 1024 bytes. (5) InBufferCount: Returns the number of bytes waiting for the read in the receiving buffer, which can be cleaned by setting the attribute 0 to clear the receiving buffer. (6) Rthreshold: This property is a valve value that determines an ONCOMM event that is ComeVReceive when the number of bytes within the received buffer reaches or exceeds the value. (7) Sthreshold: This property is a valve value that determines an ONCOMM event that generates code COMEVSEND when the number of bytes within the buffer is less than this value. (8) Inputlen: Set or return the number of bytes read in the receiving buffer, setting the property to 0 means INPUT reads the content of the entire buffer. (9) INPUT: Reads a string of characters from the receive buffer. (10) Outbuffersize: Set or return the size of the send buffer, the default is 512 bytes. (11) OutbufferCount: Returns the number of bytes sent in the transmit buffer, which can be cleaned by setting the property of 0. (12) OUTPUT: Transfer a string of characters to the send buffer. If an error or event occurs during communication, an oncomm event is triggered, and the error type is reflected by the COMMEVENT property code, and different operations can be performed in the design of the communication program. The commevent property value is as follows: (1) comevsend: value is 1, the contents of the send buffer are less than the value specified by the Sthreshold. (2) comVReceive: The value of 2, the number of characters in the receiving buffer reaches the value specified by rtHResHold. (3) COMEVFRAME: The value is 1004, the hardware detects the frame error. (4) Comevrxover: The value is 1008, and the receive buffer overflows.

(5) COMEVTXFULL: The value is 1010, and the transmission buffer overflows. (6) Comevrxparity: The value is 1009, parity error. (7) COMEVEOF: The value is 7, and the file end (ASCII code is 26) characters in the receiving data. Second, the program sample cannot use the MSCOMM control in Delphi3.0, and the author uses Delphi5.0. The MSCOMM control is the OCX control in VB. First, you need to add it to Delphi, select the menu "Component" → "Import ActiveX Control", select "Microsoft Comm Control" in the "IMPORT ACTIVEX" page, click "Install" installation, After installation, the MSCOMM icon appears in the "ActiveX" component board, you can be used. It is important to note that the input and output attributes of the MSCOMM control in Object Inspector are invisible, but they still exist, the types of these two properties are Olevariant (OLE universal variables). Below is a sample (main part) of a receiver, you can improve according to actual needs. Place a MEMO control in the Form to display the received data, ComboBoX1 Select the communication parameter (Setting property value), and the ComboBox2 selects the serial port (CommPort property value), press button to start receiving data, press Button2 to stop receiving.

Procedure TForm1.FormCreate (Sender: Tobject); Begin Mscomm1.inbuffercount: = 0; // Clearing the receiving buffer MScomm1.inputlen: = 0; // INPUT Read the entire buffer content mscomm1.rthreshold: = 1; // The time to receive the character, an ONCOMM event end; procedure tForm1.Button1Click (sender: TOBJECT); begin mscomm1.settings: = comboBox1.text; if ComboBox2.text = 'com1' Ten // Assume only two cases of COM1 and COM2 Mscomm1.commport: = 1 else mscomm1.commport: = 2; mscomm1.portopen: = true; // Open the serial port mscomm1.dtrenable: = true; // Data terminal ready MSCOMM1.rtSenable: = true; // Request to send end ; procedure TForm1.Button2Click (Sender: TObject); begin Mscomm1.PortOpen: = false; // Close serial Mscomm1.DTREnable: = false; Mscomm1.RTSEnable: = false; end; procedure TForm1.MSComm1Comm (Sender: TObject); var recstr: Olevariant; begin if Mscomm1.CommEvent = 2 then begin recstr: = Mscomm1.Input; Memo1.text: = Memo1.Text recstr; end; end; // build the main window procedure TForm1.FormCreate (Sender: TObject); Begin service_enabled: = false; timer2.enabled: = true; {window is established, open the timer} end; // PROCEDURE TFORM 1.FormClose (Sender: Tclosection); begin timer1.enabled: = false; {Close Timer} if service_enabled life; {= = = 服务 服务; {退 退 程序 {}}};;;;; button procedure TForm1.N01Click (Sender: TObject); begin form1.Close; {exit the program} end; // open the proxy service procedure TForm1.ServerSocket1Listen (Sender: TObject; Socket: TCustomWinSocket); begin Service_Enabled: = true; {set Service logo} n11.enabled: = false; n21.enabled: = true; end; // After connecting to the proxy server by the agent, establish a session and bind it with the socket ... Procedure TForm1.Serversocket1ClientConnect Sender: Tobject; Socket: Tcustomwinsocket; Var i, J: Integer; Begin J: = - 1; for i: =

1 TO sessions do {Search if there is a blank item} if not session [i-1] .used and not session [i-1] .csocket.active dam j: = i-1; {{{, assign it} session [ j] .used: = true; {{在}} Break; Else if not session [i-1] .used and session [i-1] .csocket.active the session [i-1] .csocket.active : = false; if j = -1 Then Begin {None, add one} J: = sessions; inc (sessions); setlength (session, sessions); session [j] .used: = true; { } session [j] .CSocket: = TClientSocket.Create (nil); session [j] .CSocket.OnConnect: = ClientSocket1Connect; session [j] .CSocket.OnDisconnect: = ClientSocket1Disconnect; session [j] .CSocket.OnError: = ClientSocket1Error; session [j] .CSocket.OnRead: = ClientSocket1Read; session [j] .CSocket.OnWrite: = ClientSocket1Write; session [j] .Lookingup: = false; end; session [j] .SS_Handle: = socket.socketHandle; {Save the handle to achieve the bind} session [j] .Request: = false; {No request} session [j] .client_connected: = true; {Client has connected} session [j] .remote_connected: = false; {remote_connected: = false; {remote Unconnected} edit1.text: = INTOSTR (sessions); end; // is intermitted by proxy Procedure TFORM1.SERVERSOCKET1CLIENTDISCONNECT (Sender: Tobject; Socket: Tcusto Mwinsocket); Var i, j, k: integer; begin for i: = 1 to sessions do if (session [i-1] .ss_handle = socket.sockethandle) and session [i-1] .used the beginning [i -1] .Client_connected: = false; {Client unconnected} if session [i-1] .Remote_Connected the session [i-1] .csocket.active: = false {假 远 远 连接, disconnect it} Else Session [I-1] .USED: = false; {If both are disconnected, set the resource logo} Break; end; j: = sessions; k: = 0; for i: = 1 to j DO {statistics session There are several unused items at the ends of the group} Begin if session; INC (K); End; IF K> 0 THEN {corrected session array, release tail} Begin sessions: =

sessions-k; setlength (session, sessions); end; edit1.text: = inttostr (sessions); end; // when a communication error occurs procedure TForm1.ServerSocket1ClientError (Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode : Integer; Var i, J, K: Integer; Begin for i: = 1 to sessions do if (session [i-1] .ss_handle = socket.sockethandle) and session [i-1] .used the beginning [i].. I-1] .client_connected: = false; {Client unconnected} if session [i-1] .remote_connected the session [i-1] .csocket.active: = false {假 假 连接 连接, disconnect it} Else Session [i-1] .USED: = false; {If both are disconnected, then release resource logo} Break; end; j: = sessions; k: = 0; for i: = 1 to j do beginix Session [J-I] .used the Break; INC (K); End; IF K> 0 THEN BEGIN sessions: = sessions-k; setLength (session, sessions); end; ed; edit1.text: = INTOSTR (sessions); ErrorCode: = 0; END; // Send the page Request Procedure TFORM1.Serversocket1ClientRead (Sender: Tobject; Socket: TCUStomwinsocket); VAR TMP, LINE, HOST: STRING; BEGIN i: = 1 to sessions do {judgment which session} if session [i-1] .used and (session [i-1] .ss_handle = SOC Ket. SocketHandle) THEN BEGIN Session [i-1] .Request_str: = Socket.ReceiveText; {Save Request Data} TMP: = Session [i-1] .Request_Str; {State to Temporary Variable} Memo1.Lines.Add (TMP ); J: = POS (Char (13) char (10), TMP); {a line mark} while j> 0 do {progressive scan request text, find the host address} begin line: = Copy (TMP, 1, J -1); {Take a row} delete (TMP, 1, J 1); {Delete a row} J: = POS ('Host', Line); {Host Address Sign} IF J> 0 THEN Begin Delete (Line, 1, J 5); {Delete the previous invalid character} J: = POS (':', line); if j> 0 Then Begin Host: = Copy (Line, 1, J-1); Delete (Line, 1, J) Try port: = start (line); Except port: = 80;

ELSE BEGIN HOST: = Trim (Line); {Get Host Address} Port: = 80; END; if Not session [i-1] .Remote_Connected Then {If the expedition has not been connected} Begin Session [i-1] .Request: = True; {Setting data ready mark} session [i-1] .csocket.host: = Host; {Set Remote Host Address} session [i-1] .csocket.port: = port; {Setting port} session I-1] .csocket.active: = true; {Connection Remote Host} session [i-1] .lookingup: = true; {标}} session [i-1] .lookuptime: = 0; {Start Timing from 0 } end else {If the remote is connected, send request} session [i-1] .csocket.socket.sendtext (session [i-1] .Request_str); Break; {Stop scan request text} end; j: = POS (CHAR (13) CHAR (10), TMP); {Pointing Next} end; break; {Stop loop} END; // Procedure TFORM1.CLIENTSOCKET1CONNECT (Sender: Tobject; Socket: Tcustomwinsocket) when the remote host is successful Var i: integer; begin for i: = 1 to sessions do if (session [i-1] .csocket.socket.socketHandle = Socket.socketHandle) and session [i-1] .used
Then Begin session [i -1] .csocket.tag: = socket.socketHandle; session [i-1] .remote_connected: = true; {远程 主 已 已通 标} session [i-1] .lookingup: = false; {Clear sign} Break End; end; // Procedure TFORM1.CLIENTSOCKET1DISCONNECT (Sender: Tobject; Socket: TCUSTOM when the remote host is disconnected Winsocket); Var i, j, k: integer; begin for i: = 1 to sessions do if (session [i-1] .csocket.tag = socket.sockethandle) and session [i-1] .used the beginning [I-1] .remote_connected: = false; {未 未}} if not session [i-1] .client_connected the session [i-1] .USED: = false {If the client has disconnected, then release Resource Sign} else fork: = 1 to serversocket1.socket.activeConnections do if (Serversocket1.socket.connections [k-1] .socketHandle = session [i-1] .ss_handle) And session [i-1] .used Begin serversocket1.socket.connections [k-1] .close; break; end; break; end; j: = sessions; k: = 0;

For i: = 1 to j Do Begin if session [ji] .used dam; inc (); end; if k> 0 THEN {Correction session number} begin sessions: = sessions-k; setlength (session, sessions) ; end; edit1.text: = inttostr (sessions); end; file: // when an error occurs in communication with a remote host / procedure TForm1.ClientSocket1Error (Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer) Var i, j, k: integer; begin for i: = 1 to sessions do if (session [i-1] .csocket.tag = socket.socketHandle) and session [i-1] .used the beginning, socket.close Session [i-1] .Remote_Connected: = false; {is not connected} if not session [i-1] .client_connected thession [i-1] .USED: = false {If the client has disconnected, then释 释 资 资 标} else fork: = 1 to serversocket1.socket.activeConnections do if (Serversocket1.socket.connections [k-1] .socketHandle = session [i-1] .ss_handle) and session [i-1]. Used kilin serversocket1.socket.connections [k-1] .close; Break; end; break; end; j: = sessions; k: = 0; for i: = 1 to j do begin if session [ji] .used THEN BREAK; INC (K); End; ErrorCode: = 0; IF K> 0 THEN {Correction Session Array} Begin Sessions: = sessions-k; setLength (session, sessions); end; ed; ed; end; // Send a page to remote host request Procedure TFORM1.CLIENTSOCKET1WRITE (Sender: Tobject; Socket: Tcustomwinsocket); VAR i : integer; begin for i: = 1 to sessions do if (session [i-1] .csocket.tag = socket.socketHenetle) and session [i-1] .used the beginning of session [i-1] .Request Then Begin socket.sendtext (session [i-1] .Request_str); {If there is a request, send} session [i-1] .Request: = false; {清标} end; break; end; end; // Remote host PROCEDURE TFORM1.CLIENTSOCKET1READ (Sender: Tobject; Socket: Tcustomwinsocket); REC_BYTES: Integer; REC_BYTES: Integer; REC_BYTES: INTEGER; REC_BUFFER: Array [0..2047] of char;

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

New Post(0)