Download Sockets Sockets 1 Introducción

Document related concepts
no text concepts found
Transcript
Sockets
Sockets
1
Introducción
Los URL y las conexiones URL (URLConnection) proporcionan un mecanismo de un nivel
relativamente alto (nivel 7 del modelo OSI) para acceder a los recursos de Internet.
Algunas veces, los programas requieren una comunicación a través de la red, a un nivel
un poco más bajo; por ejemplo, cuando se desea escribir una aplicación cliente / servidor.
Para este tipo de programas, se utilizan las clases Socket y ServerSocket, del paquete
java.net, que trabajan en los niveles 3 y 4 del modelo OSI.
En las aplicaciones cliente / servidor, el servidor proporciona algún servicio, como por
ejemplo: procesamiento de consultas a una base de datos o transmitir los precios actuales
de inventario. El cliente utiliza el servicio proporcionado por el servidor, ya sea
desplegando los datos de la consulta a la base de datos o haciendo recomendaciones de
compra a un inversionista, teniendo en cuenta los precios del inventario. La comunicación
entre cliente y servidor debe ser confiable; esto quiere decir que no se pueden perder
datos, y que éstos deben llegar al cliente en el mismo orden en el cual fueron enviados
por el servidor; por esta razón se utiliza TCP/IP.
TCP proporciona un canal de comunicación confiable, punto a punto, que las aplicaciones
cliente / servidor utilizan para comunicarse entre ellas a través de Internet. Para
comunicarse a través de TCP, se establece una conexión entre el programa cliente y el
programa servidor. Cada programa enlaza un socket en su extremo de la conexión. Para
comunicarse, cliente y servidor leen y escriben hacia el socket asociado a la conexión.
Cuando se escribe la parte del programa correspondiente al servidor, se abre un conector
(socket), normalmente utilizando un número de puerto conocido, y se espera a que se
conecte algún cliente. El cliente llama desde algún número de puerto no utilizado
(conocido como puerto efímero). En cuanto se conectan el cliente y el servidor, es
corriente que éste último proponga que la conversación continúe en un puerto diferente.
Este diseño deja libre el número de puerto conocido, para manejar una nueva conexión.
Una vez conectados el cliente y el servidor, hay un protocolo de más alto nivel que es
dependiente del puerto que se esté utilizando. TCP/IP reserva los prim eros 1024 puertos
para sus protocolos específicos.
La siguiente tabla muestra algunos números de puerto conocidos. Estos servicios se
ofrecen tanto en puertos TCP como en puertos UDP.
Página 1
Algoritmos y Lenguajes III
Nombre del
servicio
echo
discard
daytime
chargen
chargen
time
Sockets
Puerto Puerto
Descripción
TCP
UDP
7
7
El servidor devuelve lo que envía el cliente
9
9
El servidor descarta lo que envía el cliente
13
13
El servidor devuelve la fecha y la hora en un formato
legible
19
El servidor TCP envía un flujo continuo de caracteres
hasta que el cliente termina la conexión
19
El servidor UDP envía un datagrama, cada vez que lo
hace el cliente, que contiene un número aleatorio de
caracteres.
37
37
El servidor devuelve la hora como un número binario de
32-bits, el número de segundos desde la media noche
del 1 de enero de 1.900, UTC
Tabla 1. Puertos “Bien Conocidos”
En TCP/IP, el puerto 21 es para FTP, el 23 para Telnet, el 25 para e-mail, el 79 para
finger, el 80 para HTTP, el 119 para netnews. Cada protocolo debe determinar cómo
debe dialogar un cliente con el puerto.
2
¿Qué es un Socket?
Un socket es un conector de red.
Un conector de red es similar a un conector eléctrico. Hay distintos enchufes en la red
eléctrica que tienen una forma estándar de entregar la energía. Cualquier cosa que
entienda el protocolo estándar puede enchufarse al conector y enviar información. En los
enchufes eléctricos no importa si se conecta una lámpara o un tostador, ya que siempre
que trabajen con el voltaje adecuado, ambos funcionarán correctamente.
Pensemos cómo se crea la factura del servicio de energía eléctrica: En algún lugar entre
su casa y la red eléctrica hay un contador. Cada kilovatio que pasa a través del contador
se queda registrado y periódicamente la factura llega a nuestra “dirección”. Por eso,
aunque la electricidad fluya libremente a través de la red, todos los conectores de la casa
tienen una dirección particular. De la misma forma funcionan los conectores de la red,
excepto en que en lugar de electrones y de calles se trabaja con paquetes TCP/IP y
direcciones IP.
La noción de conector permite a un único computador atender a diferentes clientes a la
vez, además de proporcionar diferentes tipos de información. Esto se consigue utilizando
lo que se conoce com o puerto, que es un conector numerado en una máquina particular.
Se dice que un proceso servidor "escucha” en un puerto hasta que un cliente se conecta a
él. Un servidor puede aceptar múltiples clientes conectados todos ellos por el mismo
número de puerto, aunque cada sesión es única. Para gestionar las conexiones de varios
clientes, el proceso servidor debe ser un proceso multihilo o disponer de otros mecanismo
para manejar las E/S simultáneas.
Página 2
Algoritmos y Lenguajes III
Sockets
Normalmente, un servidor se ejecuta en un computador específico y tiene un socket
enlazado a un número específico de puerto. El servidor sólo espera, escuchando en el
socket, hasta que el cliente realice una solicitud de conexión.
En el lado del cliente: El cliente conoce el nombre de host de la máquina en la cual se
está ejecutando el servidor, y el número de puerto en el cual se encuentra conectado el
servidor. Para realizar la solicitud de conexión, el cliente trata de “reunirse” con el
servidor utilizando el nombre del computador donde esté se está ejecutando y el número
de puerto.
Figura 1. Solicitud de Conexión
Si todo funciona adecuadamente, el servidor acepta la conexión. Durante la aceptación, el
servidor obtiene un socket enlazado a un puerto diferente. Requiere un nuevo socket (y
por tanto un nuevo puerto), para poder continuar escuchando en el socket original por
otras solicitudes de conexión, mientras atiende las solicitudes del cliente conectado.
Figura 2. Establecimiento de la Conexión
En el lado del cliente, si la conexión es aceptada, se crea un socket, que puede ser
utilizado para comunicarse con el servidor. El socket en el lado del cliente no se enlaza
al número de puerto utilizado para establecer la conexión con el servidor. En lugar de
esto, al cliente se le asigna un número de puerto local, en la máquina en la cual se está
ejecutando.
Ahora el cliente y el servidor pueden comunicarse, escribiendo o leyendo en sus
respectivos sockets.
Definición: Un socket es el extremo de un enlace de comunicación de dos-vías
entre dos programas que se ejecutan en la red. Un socket se asocia a un número
de puerto, para que TCP pueda identificar la aplicación a la cual se están enviando
los datos.
Página 3
Algoritmos y Lenguajes III
3
Sockets
Manejo de Sockets en Java
Un objeto socket es la representación Java de una conexión de red TCP (Ver Figura).
Utilizando esta clase, un cliente puede establecer un canal de comunicación basado en
flujos de datos, con un computador remoto.
host
Socket
host:port
port
TCP
IP
IP
TCP
HTTP
Figura 3. Conexión TCP/IP usando Sockets
Para comunicarse con un host remoto, el cliente debe crear primero un Socket hacia ese
host. Esto automáticamente establece una conexión TCP, lanzando una excepción, si la
conexión falla. Además del nombre de host, es necesario especificar un puerto; éste es
un entero entre 1 y 65.535. Efectivamente, hay 65.535 direcciones diferentes en cada
host. Para conectarse a un host, es necesario especificar su dirección IP. Debe haber un
servidor escuchando activamente en el puerto especificado, o el intento de conexión
fallará.
Java proporciona dos tipos de soc kets: los de cliente, implementados en la clase Socket,
y los de servidor, implementados en la clase ServerSocket.
•
La clase Socket esconde los detalles de implementación de cualquier sistema, al
programa Java. Utilizando la clase java.net.Socket los programas Java se pueden
comunicar a través de la red, en una forma independiente de la plataforma. La clase
Socket está diseñada para conectarse a un servidor y es la que inicia el protocolo de
intercambio.
•
La clase ServerSocket, implementa un socket que el servidor puede utilizar para
escuchar y aceptar las conexiones con los clientes. La clase ServerSocket está
diseñada para “escuchar” y esperar hasta que los clientes se conecten, para
inmediatamente después empezar a prestarles el servicio solicitado.
Es importante tener en cuenta que si se está tratando de establecer una conexión al Web,
la clase URL y sus clases asociadas (URLConnection, URLEncoder) son probablemente
más apropiadas que las clases relacionadas con los sockets. De hecho, un URL es una
conexión de alto nivel al Web, y utilizan los sockets como parte de su implementación
interna.
Página 4
Algoritmos y Lenguajes III
4
Sockets
Clase Socket (Conectores TCP/IP para clientes)
Para conectarse a un host, el programa cliente tiene que incluir una línea como:
Socket conexión = new Socket (hostname, portNumber);
Si se presenta algún problema, el constructor Socket lanza una IOException. De lo
contrario, se puede suponer que el Socket está abierto y preparado para la comunicación:
BufferedReader lector = new BufferedReader (
new InputStreamReader (conexión.getInputStream()));
BufferedWriter escritor = new BufferedWriter (
new OutputStreamWriter (conexión.getOutputStream()));
Ahora se puede leer y escribir utilizando los flujos lector y escritor de la forma habitual.
Al finalizar el intercambio de datos, debe ejecutarse la instrucción:
conexión.close();
La cual cierra la conexión y a la vez cierra todos los streams, readers y writers asociados
a este Socket.
2 Restricciones de seguridad en los Applets: La mayor parte de los navegadores
incluyen un SecurityManager, que informa de una SecurityException cuando se
intenta establecer una conexión TCP/IP con un host distinto a aquel de donde se
descargó el applet. Para hacer que este código funcione en un applet, o se
autolimita para conectarse sólamente al servidor propio del applet, o se negocian
más derechos con el SecurityManager del navegador.
4.1
Constructores
Al crear un socket, se crea automáticamente una conexión a un computador y un puerto
específicos. Debe haber un servidor escuchando en el puerto del host; de lo contrario, se
lanza una excepción de tipo IOException (Conexión rechazada). Otros posibles errores
resultan de fallas en la red o nombres de hosts desconocidos.
•
Socket (String host, int port) throws IOException
Esto crea un socket y lo conecta al puerto (port) especificado, del computador (host)
especificado. El host se especifica mediante un nombre (DNS) o por una dirección IP; el
puerto debe estar en el rango 1-65535.
•
Socket (InetAddress address, int port) throws IOException
Esto crea un socket y se conecta al puerto y host especificados. La diferencia con el
constructor anterior es que la identidad del host no se especifica utilizando un String, sino
un objeto InetAddress que lo referencie. El puerto debe estar en el rango 1-65535.
Página 5
Algoritmos y Lenguajes III
•
Sockets
Socket (String host, int port, InetAddress localAddr, int localPort) throws
IOException
Esto crea un socket, lo une a la dirección y puerto locales, y lo conecta al host y puerto
remotos. Si localAddress es null, se utiliza la dirección local por defecto. Si localPort es 0
(cero), se utiliza un puerto aleatorio, de los que se encuentren desocupados.
En efecto, cada conexión TCP consiste de una dirección local y una remota, y un puerto
local y uno remoto. Cuando se crea un socket y se conecta aun host remoto,
generalmente se le asigna un número de puerto aleatorio, de los que se encuentren
desocupados.
Este constructor permite especificar la dirección y el puerto local, lo cual puede ser útil en
algunas ocasiones, para conectarse a servidores que requieren una conexión desde un
puerto particular o donde es requerido por un firewall.
•
Socket(InetAddress address, int port, InetAddress localAddr, int localPort)
throws IOException
Esto crea un socket, lo une a la dirección y puerto locales (localAddr y localPort), y lo
conecta al host y puerto remotos (address, port). Si localAddr es null, se utiliza la
dirección local por defecto. Si localPort es 0 (cero), se utiliza un puerto aleatorio, de los
que se encuentren desocupados.
•
protected Socket( )
Este constructor crea un objeto Socket sin conectar. Este socket puede unirse
posteriormente a una conexión entrante, por medio de un ServerSocket. Debe tenerse en
cuenta que este constructor sólo puede ser llamado por una subclase com o parte de una
estructura socket personalizada (custom socket framework).
•
protected Socket(SocketImpl impl)
Este constructor sólo se puede utilizar para proporcionar una implementación socket
personalizada, lo cual no se va a manejar en este curso.
4.2
Métodos
Los métodos de la clase Socket permiten la identificación del host remoto, y de los
números de puerto local y remoto, al igual que la extracción de flujos para propósitos de
comunicación bidireccional.
Para realizar comunicaciones a través de una conexión TCP, primero debe crearse un
socket y luego utilizar los métodos getInputStream() y getOutputStream() para obtener los
flujos con los cuales comunicarse al servidor remoto. En consecuencia, tanto el cliente
como el servidor tendrán un InputStream y un OutputStream, para propósitos de
comunicación.
Página 6
Algoritmos y Lenguajes III
•
Sockets
InputStream getInputStream( ) throws IOException
Este método devuelve un flujo de tipo InputStream, que permite comunicaciones basadas
en flujos a través de una conexión TCP. Todos los datos escritos por el servidor en el
extremo remoto de la conexión, deben ser leídos por este flujo de entrada.
Los datos escritos a un socket se segmentan en paquetes, para la comunicación a través
de IP. Para la aplicación, sin embargo, la conexión proporciona un flujo continuo de
datos. Por razones de eficiencia, los flujos Socket deben utilizar un buffer.
•
OutputStream getOutputStream( ) throws IOException
Este método devuelve un OutputStream que permite comunicaciones basadas en flujos, a
través de una conexión TCP. Todos los datos escritos hacia este flujo deben ser leídos
por el servidor en el extremo remoto de la conexión. Por razones de eficiencia, con este
flujo de salida deben utilizarse buffers; de lo contrario, el primer byte de un mensaje
frecuentemente será enviado en un paquete independiente, desperdiciando ancho de
banda.
•
void close( ) throws IOException
Este método cierra el socket, liberando cualquier tipo de recursos de la red y del sistema
que estén siendo utilizados. Cualquier dato enviado antes de este llamado, se entregará
exitosamente en el otro extremo de la conexión, a menos que exista una falla en la red.
Hay que tener en cuenta que si con el flujo de salida del socket se ha utilizado un
BufferedOutputStream, este debe cerrarse antes que el socket. De lo contrario, los datos
que permanezcan en el buffer se perderán. Cerrar el flujo de salida o el de entrada de un
Socket, cerrará la conexión de red; por tanto, sólo es necesario cerrar el socket, su
InputStream y su OutputStream. No existe un forma de cerrar el socket parcialmente.
•
InetAddress getInetAddress( )
Este método devuelve la dirección IP del host remoto.
•
int getPort( )
Este método devuelve el número del puerto del host remoto al cual se encuentra
conectado el socket.
•
InetAddress getLocalAddress( )
Este método devuelve la dirección local a la cual se encuentra unido el socket; es decir, la
interfaz IP local a través de la cual se están enviando los paquetes.
•
int getLocalPort( )
Este método devuelve número de puerto local al cual se encuentra unido el socket. Este
valor se asigna de forma aleatoria, si no se especifica un puerto en el constructor.
Página 7
Algoritmos y Lenguajes III
•
Sockets
void setSoTimeout(int timeout) throws SocketException
Este método establece un time-out en milisegundos, después del cual una operación de
lectura (blocking read operation) en este socket , se suspenderá automáticamente. Un
valor de cero(0), deshabilita el time-out, de modo que las operaciones se bloquean
indefinidamente. Este método es útil si se desea esperar sólo una cantidad específica de
tiempo, para que el cliente responda a ciertos datos. Si una llamada a read() alcanza el
timeout, se lanza una InterruptedException.
•
int getSoTimeout( ) throws SocketException
Este método devuelve el valor actual de time-out del socket. Un valor de cero(0) indica
que no hay time-out, o sea, que cualquier operación del socket, se bloquea
indefinidamente (el valor por defecto).
•
void setSendBufferSize(int size) throws SocketException
Este método solicita que el sistema operativo establezca el tamaño de buffer para envío
del socket (SO_SNDBUF) en el valor especificado (size). El aumento del tamaño del
buffer, puede aumentar el desempeño para el envío de grandes volúmenes de datos. El
sistema operativo puede ignorar el valor que se solicite.
•
int getSendBufferSize( ) throws SocketException
Este método devuelve el tamaño actual del buffer de envío del socket.
•
void setReceiveBufferSize(int size) throws SocketException
Este método solicita que el sistema operativo establezca el tamaño de buffer para
recepción del socket (SO_RCVBUF) en el valor especificado (size). El aumento del
tamaño del buffer, puede aumentar el desempeño para la recepción de grandes
volúmenes de datos. El sistema operativo puede ignorar el valor que se solicite.
•
int getReceiveBufferSize( ) throws SocketException
Este método devuelve el tamaño actual del buffer de recepción del socket.
•
static void setSocketImplFactory(SocketImplFactory factory) throws IOException
Este método estático puede utilizarse para instalar una implementación socket
personalizada para toda la JVM (Java Virtual Machine). Este método sólo puede llamarse
una vez, y es vetado por el SecurityManager.
4.3
•
Excepciones
IOException
Muchos de los métodos y constructores de la clase Socket pueden lanzar una
IOException, si se encuentra un error.
Página 8
Algoritmos y Lenguajes III
•
Sockets
SocketException
Esta IOException es una superclase de algunas excepciones comunes de los sockets,
que permiten un manejo más detallado de las excepciones de red. Las subclases son:
•
BindException
Esta SocketException indica que la dirección o puerto solicitados no se pudieron
enlazar al socket. Generalmente esto ocurre cuando el puerto ya está en uso o es
un puerto del sistema, o cuando la dirección local especificada no es una interfaz
local de red válida.
•
ConnectException
Esta SocketException indica que el intento de conexión fue rechazado debido a
que no hay un servidor escuchando en el puerto especificado de la máquina
remota.
•
NoRouteToHostException
Esta SocketException indica que el host remoto no pudo alcanzarse,
generalmente, debido a un problema en la red o a la presencia de un firewall.
•
SecurityException
El SecurityManager restringe la creación de sockets. Los applets no confiables, por
ejemplo, no pueden abrir sockets hacia sitios diferentes a aquel en el cual residen. Otra
restricción significativa es que un applet detrás de un firewall es posible que no pueda
hacer uso del servicio de DNS, por lo cual es necesario utilizar las dirección IP del
computador receptor, en lugar de su nombre de host.
5
Ejemplo1: Whois
El siguiente ejemplo abre una conexión con un puerto “whois” (43) del servidor InterNIC,
envía el argumento de la línea de comandos por el conector e imprime el dato recibido.
InterNIC intentará determinar el nombre de dominio Internet del argumento que recibe y
después devuelve la dirección IP e información de ese sitio.
import java.io.*;
import java.net.*;
public class Whois {
public static void main(java.lang.String[] args) throws Exception {
int c;
Socket s = new Socket ("internic.net", 43);
InputStream in = s.getInputStream() ;
OutputStream out = s.getOutputStream() ;
String str = (args.length==0 ? "starwave.com":args[0])+"\n";
byte buf[] = new byte[str.length()];
Página 9
Algoritmos y Lenguajes III
Sockets
str.getBytes (0,str.length(),buf,0);
out.write (buf);
while ((c=in.read())!=-1) {
System.out.print ((char)c);
}
s.close ();
}
}
La salida cuando no se envían parámetros al programa es:
Si, por ejemplo, se introduce sportszone.com, como argumento en la línea de comandos,
se obtendrá la siguiente salida:
Página 10
Algoritmos y Lenguajes III
6
Sockets
La Clase ServerSocket (Conectores TCP/IP para servidores)
Como se ha mencionado antes, Java tiene una clase de conector diferente que se debe
utilizar para crear aplicaciones servidoras. La clase ServerSocket se utiliza para crear
servidores que escuchan tanto a programas clientes locales como remotos que se
conectan a ellos a través de puertos conocidos.
Los objetos ServerSocket son bastante diferentes de los objetos Socket normales.
Cuando se crea un ServerSocket, éste se registra en el sistema que tiene interés en
recibir las conexiones de los cliente clientes.
6.1
Constructores
Los dos constructores de ServerSocket reflejan el número del puerto en el que se desean
aceptar las conexiones y, opcionalmente, durante cuánto tiempo se desea esperar a que
se deje de utilizar el puerto. La longitud de la cola le indica al sistema cuántas conexiones
de clientes puede dejar pendientes antes de que las conexiones sean rechazadas. Por
defecto este valor es 50. Ambos constructores pueden lanzar una IOException bajo
condiciones adversas.
Estos son los dos constructores:
• ServerSocket (int puerto)
Página 11
Algoritmos y Lenguajes III
Sockets
Crea un conector de servidor en el puerto especificado (puerto), con una longitud de cola
igual a 50.
• ServerSocket (int puerto, int número)
Crea un conec tor de servidor en el puerto especificado con una longitud de cola igual al
número especificado.
ServerSocket tiene un método adicional llamado accept ( ), que es una llamada que se
bloquea y que espera a que un cliente inicie la comunicación y después devuelve un
Socket normal que es el que se utiliza para la comunicación con el cliente.
La instrucción:
ServerSocket conexiónServidor = new ServerSocket(8000);
le indica al sistema operativo que se intenta ofrecer un servicio en el puerto 8000. (aún no
está escuchando en este puerto). Si el entorno de tiempo de ejecución es capaz de
enlazar al puerto especificado, lo hace, y configura la acumulación permitida a un valor
predeterminado de 50. (Esto significa que una vez que tenga 50 peticiones de conexión,
se rechazarán todas las peticiones sucesivas. Se puede especificar un valor de
acumulación diferente en el conector ServerSocket). Si el entorno de tiempo de ejecución
no puede enlazar al puerto (lo que ocurre cuando el puerto ya está reservado a otro
servicio), lanzará una IOException.
Una vez se haya enlazado el puerto, es posible empezar a escuchar las conexiones
llamando a accept():
Socket unSocket = conexiónServidor.accept();
Una vez hecha la conexión, accept() desbloquea el sistema y devuelve un Socket. En
éste, se puede abrir streams, readers, y writers, al igual que se hizo desde el programa
del cliente.
7
Ejemplo2: Ping en Java
Ping (Packet InterNet Groper) es un comando estándar de TCP/IP que envía permite
solicitar un mensajes de respuesta a un computador de la red o un gateway. En otras
palabras, ping envía un mensaje, para verificar si el computador al cual lo envía está
conectado y disponible en la red.
Ping envía un mensaje a un computador de la red y le avisa al usuario si recibe o no una
respuesta de ese computador. Enviar el mensaje a un computador es trivial: sólo debe
abrirse un socket en el host y escribir hacia él. Java hace todo el trabajo de ensamblar los
bytes en paquetes y enviarlos. La única duda podría ser cuál puerto utilizar. Hay muchos
servicios TCP/IP estándar. El puerto 7 es el servicio de “echo” o reenvío, y el puerto 23
es el de telnet. En este ejemplo, se va a utilizar el puerto 13, que es el puerto de la fecha
del sistema, y puede aceptar consultas TCP o UDP. Cuando se establece una conexión
Página 12
Algoritmos y Lenguajes III
Sockets
con el puerto 13 en un computador, este responde con un mensaje sencillo, que incluye la
fecha y hora actuales del computador.
import java.io.*;
import java.net.*;
public class Ping {
public static void main(java.lang.String[] args) throws Exception {
if (args.length!=1) {
System.out.println("Debe especificarse el <systemname>
como parámetro");
System.exit(0);
}
String machine = args[0];
final int daytimeport = 13;
Socket so = new Socket(machine, daytimeport);
BufferedReader br = new BufferedReader (
new InputStreamReader (so.getInputStream()));
String timestamp = br.readLine();
System.out.println( machine + " responde en: " + timestamp);
}
}
Al ejecutar el programa, debe obtenerse una respuesta como la siguiente:
Esto demuestra lo fácil que es crear una conexión socket a un puerto de otro computador,
utilizando la librería de red de Java.
Página 13
Algoritmos y Lenguajes III
8
Sockets
Ejemplo 3: Envío de un e-mail con Java
Un e-mail es enviado mediante una conexión socket con el puerto 25 de un computador.
Todo lo que se hará en este ejemplo será abrir un socket conectado al puerto 25 de un
computador, y enviar mensajes de “protocolo de correo” hacia el programa servidor
(demonio) del otro extremo. En un applet, se debe abrir un socket de retorno al servidor.
En una aplicación, se puede abrir un socket en el mismo sistema en el cual se está
ejecutando el programa. Si se utilizan correctamente los mensajes del protocolo de
correo, el sistema los entenderá y enviará el e-mail.
Este programa requiere que el programa SMTP (Simple Mail Transfer Protocol) se esté
ejecutando en el servidor. Esto puede probarse haciendo telnet al puerto 25 del servidor,
y verificar si se obtiene respuesta.
El código del programa es el siguiente:
import java.io.*;
import java.net.*;
public class Email {
public static void main(java.lang.String[] args) throws IOException{
Socket sock = new Socket("donatello",25);
BufferedReader dis = new BufferedReader(
new InputStreamReader(sock.getInputStream()));
PrintStream ps = new PrintStream (sock.getOutputStream());
ps.println("mail from: [email protected]");
System.out.println(dis.readLine());
String Address = "[email protected]";
ps.println("rcpt to: "+ Address);
System.out.println(dis.readLine());
ps.println("data");
System.out.println( dis.readLine() );
ps.println("This is the message\n that Java sent");
ps.println(".");
System.out.println( dis.readLine() );
ps.flush();
sock.close();
}
}
Página 14
Algoritmos y Lenguajes III
Sockets
Muchos de los servicios de Internet son similares a este. Se establece una conexión
socket y se utiliza un protocolo simple para comunicarle al servidor lo que se desea hacer.
Página 15