|
Redes: Enviar y recibir datos mediante el protocolo UDP con Borland Delphi 6
Explicamos cómo enviar y recibir datos mediante el protocolo UDP con Borland Delphi 6. Mostramos en este artículo cómo usar el protocolo UDP (User Datagram Protocol) para enviar y recibir datos. Para ello usamos el componente gratuito OverByte ICS para Delphi. Explicamos el funcionamiento y cómo se hizo AjpdSoft Chat UDP.
Protocolo UDP User Datagram ProtocolUDP (User Datagram Protocol) es un protocolo del nivel de transporte basado en el intercambio de datagramas. Permite el envío de datagramas a través de la red sin que se haya establecido previamente una conexión, ya que el propio datagrama incorpora suficiente información de direccionamiento en su cabecera. Tampoco tiene confirmación ni control de flujo, por lo que los paquetes pueden adelantarse unos a otros; y tampoco se sabe si ha llegado correctamente, ya que no hay confirmación de entrega o recepción. Su uso principal es para protocolos como DHCP, BOOTP, DNS y demás protocolos en los que el intercambio de paquetes de la conexión/desconexión son mayores, o no son rentables con respecto a la información transmitida, así como para la transmisión de audio y vídeo en tiempo real, donde no es posible realizar retransmisiones por los estrictos requisitos de retardo que se tiene en estos casos. En la familia de protocolos de Internet UDP proporciona una sencilla interfaz entre la capa de red y la capa de aplicación. UDP no otorga garantías para la entrega de sus mensajes y el origen UDP no retiene estados de los mensajes UDP que han sido enviados a la red. UDP sólo añade multiplexado de aplicación y suma de verificación de la cabecera y la carga útil. Cualquier tipo de garantías para la transmisión de la información deben ser implementadas en capas superiores La cabecera UDP consta de 4 campos de los cuales 2 son opcionales. Los campos de los puertos fuente y destino son campos de 16 bits que identifican el proceso de origen y recepción. Ya que UDP carece de un servidor de estado y el origen UDP no solicita respuestas, el puerto origen es opcional. En caso de no ser utilizado, el puerto origen debe ser puesto a cero. A los campos del puerto destino le sigue un campo obligatorio que indica el tamaño en bytes del datagrama UDP incluidos los datos. El valor mínimo es de 8 bytes. El campo de la cabecera restante es una suma de comprobación de 16 bits que abarca la cabecera, los datos y una pseudo-cabecera con las IP origen y destino, el protocolo, la longitud del datagrama y 0's hasta completar un múltiplo de 16, pero no los datos. El checksum también es opcional, aunque generalmente se utiliza en la práctica.
Enviar datos usando el protocolo UDP y Borland Delphi, AjpdSoft Chat UDPInstalar componente gratuito OverByte ICS en DelphiPara el caso de Borland Delphi 6 descargaremos OverByte ICS versión 5.0 (Download ICS-V5 Distribution (Sep 12, 2009)).
Una vez descargado el ficheo "OverbyteIcsV5.zip", lo descomprimiremos y copiaremos el contenido de la carpeta "Delphi/Vc32": Y lo pegaremos en la carpeta Lib de la instalación de Delphi: Abriremos Delphi 6, accederemos al menú "File" - "Open": Seleccionaremos el fichero "IcsDelphi60.dpk" de la carpeta "Lib" de Delphi: Pulsaremos el botón "Install" en la ventana de Package de IcsDel60.dpk: Si todo es correcto mostrará una ventana como la siguiente:
Nota: a veces hay que copiar el contenido de la subcarpeta ZOBJ123 de la carpeta Vc32 a la carpeta Lib de Borland Delphi. Crear aplicación Chat UDP en Delphi con OverByte ICS, AjpdSoft Chat UDPAbriremos Borland Delphi, crearemos un nuevo proyecto ("File" - "New" - "Application"), en el formlulario principal añadiremos los siguientes componentes:
A continuación mostramos el código fuente (source code) en Borland Delphi 6 (válido para otras versiones) de la aplicación completa, de las funciones, de los botones y los eventos de los componentes WSocket: unit UnidadMenuPrincipal; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, shellapi, WSocket, WinSock, ComCtrls; type TformMenuPrincipal = class(TForm) GroupBox1: TGroupBox; Label1: TLabel; Label2: TLabel; txtIPDestinatario: TEdit; txtPuerto: TEdit; txtChat: TMemo; txtTexto: TMemo; LWEB: TLabel; bEnviar: TButton; wSocketEnviar: TWSocket; wSocketLeer: TWSocket; be: TStatusBar; bActivarLeer: TButton; bPararLeer: TButton; txtNick: TEdit; Label3: TLabel; procedure LWEBClick(Sender: TObject); procedure bEnviarClick(Sender: TObject); procedure wSocketEnviarDataSent(Sender: TObject; ErrCode: Word); procedure wSocketLeerDataAvailable( Sender: TObject; ErrCode: Word); procedure wSocketLeerSessionConnected( Sender: TObject; ErrCode: Word); procedure wSocketLeerSessionClosed( Sender: TObject; ErrCode: Word); procedure bActivarLeerClick(Sender: TObject); procedure bPararLeerClick(Sender: TObject); procedure wSocketEnviarError(Sender: TObject); procedure wSocketEnviarSessionConnected(Sender: TObject; ErrCode: Word); private { Private declarations } FSenderAddr : TInAddr; public { Public declarations } end; var formMenuPrincipal: TformMenuPrincipal; implementation {$R *.dfm} function atoi(value : string) : Integer; var i : Integer; begin Result := 0; i := 1; while (i <= Length(Value)) and (Value[i] = ' ') do i := i + 1; while (i <= Length(Value)) and (Value[i] in ['0'..'9']) do begin Result := Result * 10 + ord(Value[i]) - ord('0'); i := i + 1; end; end; procedure TformMenuPrincipal.LWEBClick(Sender: TObject); begin ShellExecute(Handle, Nil, PChar('http://www.ajpdsoft.com'), Nil, Nil, SW_SHOWNORMAL); end; procedure TformMenuPrincipal.bEnviarClick(Sender: TObject); begin wSocketEnviar.Proto := 'udp'; wSocketEnviar.Addr := txtIPDestinatario.Text; wSocketEnviar.Port := txtPuerto.Text; //wSocketEnviar.LocalPort := txtPuerto.Text; wSocketEnviar.Connect; wSocketEnviar.SendStr('[' + txtNick.Text + '] ' + txtTexto.Text); end; procedure TformMenuPrincipal.wSocketEnviarDataSent(Sender: TObject; ErrCode: Word); begin be.Panels[0].Text := 'Enviando datos'; wSocketEnviar.Close; end; procedure TformMenuPrincipal.wSocketLeerDataAvailable( Sender: TObject; ErrCode: Word); var Buffer : array [0..1023] of char; Len : Integer; Src : TSockAddrIn; SrcLen : Integer; begin be.Panels[0].Text := 'Leyendo datos'; SrcLen := SizeOf(Src); Len := wSocketLeer.ReceiveFrom(@Buffer, SizeOf(Buffer), Src, SrcLen); if Len >= 0 then begin if (FSenderAddr.S_addr = INADDR_ANY) or (FSenderAddr.S_addr = Src.Sin_addr.S_addr) then begin Buffer[Len] := #0; txtChat.Text := txtChat.Text + chr(13) + chr(10) + IntToStr(atoi(txtChat.Text) + 1) + ' ' + StrPas(inet_ntoa(Src.sin_addr)) + ':' + IntToStr(ntohs(Src.sin_port)) + '--> ' + StrPas(Buffer); end; end; end; procedure TformMenuPrincipal.wSocketLeerSessionConnected( Sender: TObject; ErrCode: Word); begin bActivarLeer.Enabled := false; bPararLeer.Enabled := true; be.Panels[0].Text := 'Conectado (lectura)'; end; procedure TformMenuPrincipal.wSocketLeerSessionClosed( Sender: TObject; ErrCode: Word); begin bActivarLeer.Enabled := True; bPararLeer.Enabled := false; be.Panels[0].Text := 'Desconectado (lectura)'; end; procedure TformMenuPrincipal.bActivarLeerClick( Sender: TObject); begin FSenderAddr := WSocketResolveHost('0.0.0.0'); if FSenderAddr.S_addr = htonl(INADDR_LOOPBACK) then FSenderAddr := WSocketResolveHost(LocalHostName); wSocketLeer.Proto := 'udp'; wSocketLeer.Addr := '0.0.0.0'; wSocketLeer.Port := txtPuerto.Text; wSocketLeer.Listen; end; procedure TformMenuPrincipal.bPararLeerClick(Sender: TObject); begin bActivarLeer.Enabled := true; bPararLeer.Enabled := false; wSocketEnviar.Close; end; procedure TformMenuPrincipal.wSocketEnviarError( Sender: TObject); begin be.Panels[0].Text := 'Error en envío'; end; procedure TformMenuPrincipal.wSocketEnviarSessionConnected( Sender: TObject; ErrCode: Word); begin be.Panels[0].Text := 'Conectado'; end; end. Aplicación AjpdSoft Chat UDP en funcionamiento, apertura de puerto en Router o FirewallEn primer lugar, si tenemos un router o un cortafuegos en nuestra red deberemo abrir o mapear el puerto elegido para el protocolo UDP, en el siguiente artículo explicamos cómo mapear o redireccionar un puerto a un equipo de nuestra red en un router: Abrir puertos en router DSL-G804V y firewall de Windows para optimizar eMule Abriremos la aplicación AjpdSoft Chat UDP en el primer equipo, introduciremos en "IP destinatario" la IP o hostname del equipo de destino (al que enviaremos los mensajes UDP), en "Puerto" introduciremos el puerto que usaremos para la comunicación, en "Nick" introduciremos el nombre de usuario. Introduciremos estos datos y pulsaremos "Activar leer": En otro equipo, realizaremos la misma operación, abriremos AjpdSoft Chat UDP, introduciremos la IP del destinatario (la IP o hostname del equipo anterior), el mismo puerto, el nombre de usuario y pulsaremos "Activar Leer": Para enviar mensajes entre equipos será suficiente con escribir el texto del mensaje (en el cuadro de texto de la parte inferior y pulsar el botón "Enviar". Si todo es correcto, la aplicación destino recibirá el mensaje y lo mostrará en el cuadro de texto, mostrará la IP origen, el puerto usado, el nick del emisor y el mensaje:
Artículos relacionados
CréditosArtículo realizado íntegramente por Alonsojpd miembro fundador del proyecto AjpdSoft. Anuncios
Enviado el Miércoles, 08 diciembre a las 01:11:10 por ajpdsoft
|
|