Red de conocimiento informático - Conocimiento informático - ¿Cómo escribir un programa que utilice comunicación Socket?

¿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

utiliza

Windows, Mensajes, SysUtils, Clases, Gráficos, Controles, Formularios, Diálogos,

ScktComp, ToolWin, ComCtrls, ExtCtrls, StdCtrls, Botones;

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

}

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;

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...';

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

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.