¿Cómo escribir un programa que utilice comunicación Socket?
Ideas de diseño
Este ejemplo incluye un programa del lado del servidor y un programa del lado del cliente. El programa cliente se puede ejecutar en varias computadoras y comunicarse con el servidor al mismo tiempo.
El objetivo de este ejemplo es, primero, demostrar cómo se comunican el cliente y el servidor; segundo, cuando varios clientes están conectados al servidor al mismo tiempo, cómo el servidor identifica a cada cliente y responde al mismo. Solicitud Dar respuestas adecuadas. Para garantizar que cuando un cliente se desconecta, no afecte la comunicación entre otros clientes y el servidor, y para garantizar que el servidor pueda responder correctamente a la solicitud del cliente, en este ejemplo se declara un tipo de registro:
tipo
p>client_record=record
CHandle: integer; // Identificador del socket del cliente
CSocket:TCustomWinSocket //Socket del cliente
CName: string; //Nombre de la computadora del cliente
CAddress:string; //Dirección IP de la computadora del cliente
CUsed: //Indicador en línea del cliente
end;
Utilice este tipo de datos de registro para guardar información del cliente y guardar el estado actual de la conexión del cliente. Entre ellos, CHandle guarda el identificador del socket del cliente para ubicar con precisión a cada cliente que mantiene una conexión con el servidor; Csocket guarda el socket del cliente a través del cual se puede responder al cliente. Cused registra si el cliente actual mantiene una conexión con el servidor.
A continuación se ofrece una breve explicación de la configuración de propiedades de los componentes ServerSocket y ClientSocket.
Propiedades de ServerSocket:
· Puerto es el puerto de comunicación y debe configurarse. En este ejemplo, está configurado en 1025;
· ServerTypt, el tipo de información de lectura y escritura del lado del servidor, está configurado en stNonBlocking para indicar lectura y escritura asincrónica de información, y este método se utiliza en este ejemplo.
· ThreadCacheSize, el número máximo de conexiones de cliente, es el número máximo de conexiones simultáneas permitidas por el servidor. Este ejemplo utiliza el valor predeterminado de 10.
Utilice la configuración predeterminada para otras propiedades.
Propiedades de ClientSocket:
· Puerto es el puerto de comunicación, que debe ser el mismo que la configuración del lado del servidor. En este ejemplo, se establece en 1025;
· ClientType, el tipo de información de lectura y escritura del cliente, debe ser el mismo que la configuración del servidor stNonBlocking indica información de lectura y escritura asincrónica.
· Host, la dirección IP del servidor al que el cliente quiere conectarse. Debe configurarse; por supuesto, también se puede configurar dinámicamente en el código.
Utilice la configuración predeterminada para otras propiedades.
Código fuente del programa:
· Código fuente del lado del servidor (uServerMain.pas):
unidad uServerMain;
interfaz p>
utiliza
Windows, Mensajes, SysUtils, Clases, Gráficos, Controles, Formularios, Diálogos,
ScktComp, ToolWin, ComCtrls, ExtCtrls, StdCtrls, Botones; p>
const
CMax=10; //Número máximo de conexiones de cliente
tipo
client_record=record
CHandle : integer ; // Identificador del socket del cliente
CSocket:TCustomWinSocket; //Socket del cliente
CName:string; //Nombre de la computadora del cliente
CAddress:string; //Dirección IP del equipo cliente
CUsed: boolean; //Indicador en línea del cliente
end;
tipo
TfrmServerMain = class( TForm)
ServerSocket: TServerSocket;
ControlBar1: TControlBar;
ToolBar1: TToolBar;
tbConnect: TToolButton;
tbClose: TToolButton;
tbDisconnected: TToolButton;
Edit1: TEdit;
Memo1: TMemo;
StatusBar: TStatusBar ;
procedimiento tbConnectClick(Remitente: TObject);
procedimiento tbDisconnectedClick(Remitente: TObject);
procedimiento ServerSocketClientRead(Remitente: TObject;Socket: TCustomWinSocket);
procedimiento ServerSocketListen(Remitente: TObject;Socket: TCustomWinSocket);
procedimiento ServerSocketClientConnect(Remitente: TObject;Socket: TCustomWinSocket);
procedimiento ServerSocketClientDisconnect(Remitente: TObject;Socket: TCustomWinSocket);
procedimiento tbCloseClick(Remitente: TObject);
procedimiento FormCreate(Remitente: TObject);
procedimiento FormClose(Remitente: TObject ; var Acción: TCloseAction);
procedimiento ServerSocketGe
tSocket(Remitente: TObject; Socket: Integer;
var ClientSocket: TServerClientWinSocket);
procedimiento ServerSocketClientError(Remitente: TObject;
Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
privado
{
Declaraciones privadas
} p>
public
{
Declaraciones públicas
}
sesión: matriz[0..CMax] de client_record; //Matriz de conexión del cliente
Sesiones: entero; //Número de conexión del cliente
end;
var
frmServerMain: TfrmServerMain ;
implementación
{$R *.DFM}
//Abre la conexión del socket y pon el socket en estado de escucha
procedimiento TfrmServerMain.tbConnectClick(Sender: TObject);
comenzar
ServerSocket.Open;
end;
// Cerrar la conexión del socket y ya no escuchar las solicitudes de los clientes
procedimiento TfrmServerMain.tbDisconnectedClick(Sender: TObject);
comenzar
ServerSocket.Close;
p>StatusBar.Panels[0].Text :='La conexión del socket del servidor se ha cerrado y no se puede aceptar la solicitud de conexión del cliente.';
end;
/ /Leer información del cliente
procedimiento TfrmServerMain.ServerSocketClientRead(Sender: TObject;Socket: TCustomWinSocket);
var
i:integer;
comenzar
//Agrega la información leída del cliente a Memo1
Memo1.Lines.Add(Socket.ReceiveText);
for i:=0 a las sesiones hacer
comenzar
//Obtener el cliente correspondiente
si sesión[i].CHandle = Socket.SocketHandle entonces
comenzar
sesión[i].CSocket.SendText('Responder al cliente'+sesión[i].CAddress+' ==> '+Edit1.Text);
fin; p>
end;
end;
// El socket del lado del servidor entra en estado de escucha para monitorear la conexión del cliente
procedimiento TfrmServ
erMain.ServerSocketListen(Remitente: TObject;Socket: TCustomWinSocket);
comenzar
StatusBar.Panels[0].Text :='Esperando conexión del cliente...'; p>
end;
//Cuando el cliente se conecta al servidor
procedimiento TfrmServerMain.ServerSocketClientConnect(Remitente: TObject;
Socket: TCustomWinSocket ) ;
var
i,j:integer;
comenzar
j:=-1;
para i:=0 a las sesiones
comienzan
//Hay conexiones de cliente interrumpidas en la matriz de conexiones de cliente original
si no es la sesión [i]. CUsed luego
comenzar
sesión[i].CHandle := Socket.SocketHandle;// Identificador del socket del cliente
sesión[i].CSocket := Socket ; //Socket del cliente
sesión[i].CName := Socket.RemoteHost; //Nombre del ordenador del cliente
sesión[i ].CAddress := Socket.RemoteAddress ;// IP del equipo cliente
sesión[i].CUsed := True; //La posición actual en la matriz de conexiones ya está ocupada
Break;
end;
j:=i;
fin;
si j=sesiones entonces
comenzar
inc( sesiones);
sesión[j].CHandle := Socket.SocketHandle ;
sesión[j].CSocket := Socket;
sesión[j] .CName := Socket.RemoteHost ;
sesión[j].CAddress := Socket.RemoteAddress ;
sesión[j].CUsed := True;
fin;
StatusBar.Panels[0].Text := 'Cliente'+Socket.RemoteHost + 'Conectado';
fin ;
// Cuando el cliente se desconecta
procedimiento TfrmServerMain.ServerSocketClientDisconnect(Sender: TObject;
Socket: TCustomWinSocket);
var
i:integer ;
comenzar
para i:=0 a sesiones hacer
comenzar
si sesión[i].CHandle =Socket.SocketHandle luego
comenzar
sesión[i].CH
andle :=0;
sesión[i].CUsed := False;
Romper;
fin;
fin;
StatusBar.Panels[0].Text :='Client'+Socket.RemoteHost + 'Desconectado';
end;
//Cerrar ventana p>
procedimiento TfrmServerMain.tbCloseClick(Remitente: TObject);
comenzar
Cerrar;
finalizar;
procedimiento TfrmServerMain .FormCreate(Remitente: TObject);
comenzar
sesiones:= 0;
finalizar;
procedimiento TfrmServerMain. : TObject;var Acción: TCloseAction);
begin
ServerSocket.Close;
end;
//Cuando Cuando el cliente se está conectando al servidor
procedimiento TfrmServerMain.ServerSocketGetSocket(Sender: TObject;
Socket: Integer; var ClientSocket: TServerClientWinSocket);
begin
StatusBar.Panels[0].Text :='El cliente se está conectando...';
end;
//Se produjo un error en el cliente
p>procedimiento TfrmServerMain.ServerSocketClientError(Remitente: TObject;
Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
comenzar
StatusBar.Panels[0].Text :='Client'+Socket.RemoteHost +'¡Ocurrió un error! ';
Código de error := 0;
fin;
fin.