The author encountered problems with Socket communication between the workstations and servers in the local area network. The basic usage of the TServersocket and TClientSockets that I summarized now will be written out, I hope to share with you. The ClientSocket component is a client component. It is a request for communication, that is, it is actively connected to the server side. The Serversocket component is a server-side component. It is the response party of communication, that is, its action is to monitor and passively accept the client's connection request and respond to the request. The ServerSocket component can receive a connection request for one or more ClientSocket components, and establish a separate connection with each ClientSocket component for separate communication. Therefore, a server side can serve multiple clients.
Design ideas
This example includes a server-side program and a client program. The client program can be run on multiple computers while connecting to the server side. The focus of this example is to demonstrate how the client communicates with the server; Second, when multiple clients are connected to the server side, the server-side identifies each client and gives the corresponding reply to the request. In order to ensure that a client is disconnected, it does not affect other clients and server-side communications, while ensuring that the server side can correctly reply to the client's request, in this case, a record type is declared:
Type
Client_record = Record
Chandle: integer; // Client sleeve
CSocket: tcustomwinsocket; // Client sleeve
CNAME: String; // Client Computer Name
Caddress: String; // Client Computer IP Address
Cused: boolean; // Client online flag
END;
Use this record type data to save the client's information while saving the current client connection status. Among them, Chandle saves the client sleeve in order to accurately locate the client that is connected to the server side; CSocket Saves the client sleeve, and can reply to the client. CUSED records if the current client is connected to the server side. The following is a brief description of the properties of the component ServerSocket and ClientSocket. ServerSocket properties: · Port, is the port of communication, must be set. In this example, it is set to 1025; • Servertypt, the server end reads the information type, set to stnonblocking to represent asynchronous read and write information, this way in this example. · ThreadCachesize, the maximum number of clients, is the server-side that allows the number of clients to be simultaneously connected. This example uses the default value 10. Other properties can be used by default settings. ClientSocket properties: · Port, is the port of communication, must be the same as the server side. In this example, it is set to 1025; · ClientType, the client reads write information type should be the same as the server side, indicating asynchronous read and write information for STNONBLOCKING. · Host, the client's IP address of the server is connected. It must be set, of course, can also be dynamically set in the code. Other properties can be used by default settings. Program source code: • Server end source code (Uservermain.pas):
Unit UserverMain;
Interface
Uses
Windows, Messages, Sysutils, Classes, Graphics, Controls, Forms, Dialogs,
Scktcomp, Toolwin, Comctrls, Extctrls, Stdctrls, Buttons; Const
CMAX = 10; // Client maximum connection number
Type
Client_record = Record
Chandle: integer; // Client sleeve
CSocket: tcustomwinsocket; // Client sleeve
CNAME: String; // Client Computer Name
Caddress: String; // Client Computer IP Address
Cused: boolean; // Client online flag
END;
Type
TFRMSERVERMAIN = Class (TFORM)
Serversocket: TSERVERSOCKET;
Controlbar1: tControlbar;
Toolbar1: Ttoolbar;
TbConnect: TtoolButton;
TBClose: TtoolButton;
TBDisconnected: TtoolButton;
EDIT1: TEDIT;
Memo1: TMEMO;
Statusbar: TSTATUSBAR;
Procedure TBConnectClick (Sender: TOBJECT);
Procedure TBDisconnectedClick (Sender: TOBJECT);
Procedure ServersocketClientRead (Sender: TOBJECT)
Socket: tcustomwinsocket;
Procedure ServersocketListen (Sender: TOBJECT)
Socket: tcustomwinsocket;
Procedure ServerSocketClientConnect (Sender: Tobject)
Socket: tcustomwinsocket;
Procedure ServersocketClientDisconnect (Sender: TOBJECT)
Socket: tcustomwinsocket;
Procedure TBCloseclick (Sender: TOBJECT);
Procedure formcreate (Sender: TOBJECT);
Procedure formclose (Sender: Tobject; VAR Action: Tclosection);
Procedure ServersocketGetSocket (Sender: Tobject; Socket: Integer;
VAR ClientSocket: TSERVERCLIENTWInsocket;
Procedure ServersocketClientError (Sender: Tobject)
Socket: tcustomwinsocket; erroorevent: TerrorEvent;
Var ErrorCode: integer;
Private
{Private Declarations}
public
{Public declarations}
Session: array [0..cmax] of client_record; // Client connection array
Sessions: integer; / / client connection
END;
VAR
FRMSERVERMAIN: TFRMSERVERMAIN;
IMPLEMentation
{$ R * .dfm}
/ / Open the socket connection and enable the socket into the listening state
Procedure tfrmservermain.tbconnectclick (sender: TOBJECT);
Begin
Serversocket.open;
// Close the socket connection and no longer listen to the client's request
Procedure tfrmservermain.tbdisconnectedclick (sender: TOBJECT);
Begin
Serversocket.close;
Statusbar.Panels [0] .text: = 'server socket connection has been closed, unable to accept client connection requests.';
END;
/ / Read information from the client
Procedure tfrmservermain.serversocketClientRead (Sender: TOBJECT)
Socket: tcustomwinsocket;
VAR
i: integer;
Begin
// Add information read from the client to MEMO1
Memo1.Lines.Add (socket.ReceiveText);
For i: = 0 to sessions do
Begin
// acquire the matching client
IF session [i] .chaandle = socket.socketHandle Then
Begin
Session [i] .csocket.sendtext ('Reply Client' Session [i] .caddress '==>' Edit1.Text);
END;
END;
END;
// server end socket enters the listening state to listen to the client's connection
Procedure tfrmservermain.serversocketlisten (Sender: Tobject)
Socket: tcustomwinsocket;
Begin
Statusbar.Panels [0] .Text: = 'Waiting for the client connection ...';
END;
// After the client is connected to the server side
Procedure TfrmServermain.serversocketClientConnect (Sender: Tobject)
Socket: tcustomwinsocket;
VAR
I, J: Integer;
Begin
J: = - 1;
For i: = 0 to sessions do
Begin
// Interrupt client connection in the original client connection array
IF not session [i] .cused then
Begin
Session [i] .chaandle: = Socket.socketHandle; // Client sleeve
Session [i] .csocket: = socket; // Client sleeve
Session [i] .cname: = socket.remotehost; // Client computer name
Session [i] .caddress: = socket.remoteaddress; // Client Computer IP
Session [i] .cused: = true; // The current location of the connection number has been occupied
Break;
END;
J: = i;
END;
IF j = sessions.
Begin
Inc (sessions);
Session [J] .cHandle: = Socket.socketHen;
Session [J] .csocket: = Socket;
Session [J] .cname: = Socket.Remotehost;
Session [J] .caddress: = Socket.Remoteaddress;
Session [J] .cused: = true;
END;
StatusBar.Panels [0] .text: = 'Client' Socket.Remotehost 'has been connected';
// When the client is disconnected
Procedure tfrmservermain.serversocketClientDisconnect (Sender: TOBJECT)
Socket: tcustomwinsocket;
VAR
i: integer;
Begin
For i: = 0 to sessions do
Begin
IF session [i] .chaandle = socket.socketHandle Then
Begin
Session [i] .cHandle: = 0;
Session [i] .cused: = false;
Break;
END;
END;
Statusbar.Panels [0] .text: = 'Client' Socket.Remotehost 'has been disconnected;
END;
//close the window
Procedure tfrmservermain.tbcloseclick (sender: TOBJECT);
Begin
CLOSE;
END;
Procedure tfrmservermain.formcreate (sender: TOBJECT);
Begin
Sessions: = 0;
END;
Procedure tfrmservermain.formclose (Sender: TOBJECT)
VAR action: tclosection;
Begin
Serversocket.close;
END;
// When the client is connected to the server side
Procedure tfrmservermain.serversocketgetsocket (Sender: TOBJECT)
Socket: Integer; Var ClientSocket: TSERVERCLIENTWINSOCKET);
Begin
Statusbar.Panels [0] .text: = 'The client is connecting ...';
END;
/ / Client error
Procedure tfrmservermain.serversocketClienTerror (Sender: TOBJECT)
Socket: tcustomwinsocket; erroorevent: TerrorEvent;
Var ErrorCode: integer;
Begin
Statusbar.Panels [0] .text: = 'Client' Socket.Remotehost 'error! "
ErrorCode: = 0;
END;
End.
· Client source code (uclientmain.pas):
Unit uclientmain;
Interface
Uses
Windows, Messages, Sysutils, Classes, Graphics, Controls, Forms, Dialogs,
Scktcomp, Comctrls, Toolwin, Extctrls, stdctrls, buttons;
Const
SocketHost = '172.16.1.6'; // server end address
Type
TfrmClientMain = Class (TFORM)
Controlbar1: tControlbar;
Toolbar1: Ttoolbar;
TbConnected: TtoolButton;
TBSEND: TTOOLBUTTON;
TBClose: TtoolButton;
TBDisconnected: TtoolButton; ClientSocket: TclientSocket;
EDIT1: TEDIT;
Memo1: TMEMO;
Statusbar: TSTATUSBAR;
Btnsend: TbitBtn;
Procedure TBConnectedClick (Sender: TOBJECT);
Procedure TBDisconnectedClick (Sender: TOBJECT);
Procedure ClientSocketread (Sender: Tobject; Socket: Tcustomwinsocket);
Procedure TBSendClick (Sender: TOBJECT);
Procedure TBCloseclick (Sender: TOBJECT);
Procedure FormShow (Sender: TOBJECT);
Procedure ClientsocketConnect (Sender: TOBJECT)
Socket: tcustomwinsocket;
Procedure ClientsocketConnecting (Sender: TOBJECT)
Socket: tcustomwinsocket;
Procedure ClientsocketDisconnect (Sender: Tobject)
Socket: tcustomwinsocket;
Procedure formclose (Sender: Tobject; VAR Action: Tclosection);
Procedure ClientsocketError (Sender: Tobject; Socket: tcustomwinsocket;
ErroorEvent: TerRorevent; Var ErrorCode: Integer;
Private
{Private Declarations}
public
{Public declarations}
END;
VAR
FRMCLIENTMAIN: TFRMCLIENTMAIN;
IMPLEMentation
{$ R * .dfm}
// Open the socket connection
Procedure tfrmclientmain.tbconnectedclick (sender: TOBJECT);
Begin
Clientsocket.open;
END;
// Close the socket connection
Procedure tfrmclientmain.tbdisconnectedclick (sender: TOBJECT);
Begin
Clientsocket.close;
END;
/ / Accept the reply of the server side
Procedure TfrmClientMain.ClientSocketRead (Sender: Tobject)
Socket: tcustomwinsocket;
Begin
Memo1.Lines.Add (socket.ReceiveText);
END;
// Send information to the server side
Procedure TfrmClientmain.tbsendClick (Sender: TOBJECT);
Begin
Clientsocket.socket.sendtext (edit1.text);
END;
Procedure tfrmclientmain.tbcloseclick (sender: TOBJECT);
Begin
CLOSE;
END;
/ / Set the server side address to be connected
Procedure TfrmClientMain.FormShow (Sender: TOBJECT);
Begin
Clientsocket.host: = sockethost;
END;
/ / Already connected to the server
Procedure TfrmClientmain.ClientSocketConnect (Sender: TOBJECT)
Socket: tcustomwinsocket; begin
TBSEND.ENABLED: = TRUE;
TbDisconnected.enable;
btnsend.enabled: = true;
Statusbar.Panels [0] .text: = 'has been connected to' socket.remotehost;
END;
// is connected to the server side
Procedure TfrmClientMain.ClientSocketConnecting (Sender: TOBJECT)
Socket: tcustomwinsocket;
Begin
Statusbar.Panels [0] .text: = 'is connected to the server ...';
END;
/ / When the connection to the server is disconnected
Procedure TfrmClientMain.ClientSocketdisconnect (Sender: Tobject)
Socket: tcustomwinsocket;
Begin
TBSEND.ENABLED: = false;
btnsend.enabled: = false;
TbDisconnected.enabled: = false;
Statusbar.Panels [0] .text: = 'has been disconnected with' socket.Remotehost ';
END;
Procedure TfrmClientmain.formClose (Sender: TOBJECT)
VAR action: tclosection;
Begin
Clientsocket.close;
END;
// When an error occurs with the server side
Procedure TfrmClientmain.ClientSocketError (Sender: TOBJECT)
Socket: tcustomwinsocket; erroorevent: TerrorEvent;
Var ErrorCode: integer;
Begin
StatusBar.Panels [0] .Text: = 'Errors with the server side';
ErrorCode: = 0;
END;
End.