Tutorial: conexión a red en dispositivos móviles
Versión: 1.0, Septiembre, 2006 Autor: Manuel Gómez Olmedo Web: http://decsai.ugr.es/~mgomez, Mail: mgomez@decsai.ugr.es |
(C) Dpto. de CCIA Web: http://decsai.ugr.es |
En este tutorial se explica la forma de conectar un dispositivo móvil con la red. La
exposición se basará en la realización de una serie de ejercicios que
irán introduciendo los conceptos necesarios. Se incluyen algunos comentarios sobre
operaciones de entrada/salida que son necesarias para poder intercambiar datos mediante
las conexiones pertinentes.
Para quien conozca Java estándar, hay poca diferencia entre la forma de programar la conexión a red en Java para dispositivos móviles. Para apreciar esta semejanza, el primer ejemplo consistirá en el desarrollo completo de un MIDlet que obtendrá datos a partir de una conexión de red y los mostrará por pantalla.
La aproximación a conexión a redes parte de la definición de un marco genérico de conexión (GCF: generic connection framework). El propósito de este marco genérico es ofrecer un nivel de abstracción para los servicios de red, lo que permite que diferentes dispositivos habiliten únicamente los protocolos de red precisos para sus necesidades.
En verdad, el dispositivo no es quien para decidir las características de conectividad que soportará. Esto es responsabilidad de los diferentes perfiles. El marco GCF define una clase genérica, Connector, que está incluida en el paquete javax.microedition.io. Esta clase, junto con un conjunto de interfaces que definen los tipos de conexiones sirven como plataforma de tratamiento de la conexión de los MIDlets con la red. Se exponen algunas de las características relevantes de las clases a usar para ofrecer la conexión a red:
En realidad se trata de un conjunto de interfaces generales que no están próximas a ningún protocolo real de comunicaciones. Ofrecen, por tanto, una arquitectura básica capaz de soportar un amplio rango de características de conexión. Esto tiene la ventaja de conseguir que las aplicaciones de conexión a red tengan una estructura similar independientemente del protocolo de red usado.
Para implementar esta arquitectura general, los perfiles agregarán las clases necesarias para complementar esta plataforma básica. Por ejemplo, el API de MIDP agrega la interfaz HttpConnection, que agrega la posibilidad de establecer conexiones HTTP (conexiones a páginas web). En realidad, la conexión HTTP es la única que obligatoriamente debe incluir la implementación de MIDP. Por tanto, siguiendo de forma estricta el estándar MIDP es el único tipo de conexión posible. Esto es, de alguna forma, una limitación con gran impacto en el diseño de MIDlets.
Siempre se usa la clase Connector para establecer conexiones de red, independientemente del tipo de conexión. Todos los métodos de esta clase son estáticos, siendo el más importante el método open(), con tres versiones diferentes:
El primer parámetro de estos métodos es la cadena de conexión. Se trata del parámetro más importante, ya que determina el tipo de conexión a realizar. La cadena de conexión describe qué tipo de conexión se usará y debe seguir el esquema: Protocolo:Objetivo[;Parámetros]
El parámetro Protocolo es el nombre del protocolo a usar, como http o ftp. El parámetro Objetivo es, típicamente, el nombre de la dirección de red a acceder, pero puede variar según el protocolo usado. El último argumento, Parámetros, es una lista de parámetros asociados a la conexión. Algunos ejemplos de diferentes tipos de conexión se incluyen a continuación:
Hemos de tener en cuenta que el único tipo de conexión que MIDP soporta es la conexión HTTP. Disponer o no de las otras dependerá de la implementación de MIDP que se use.
La segunda y tercera versión del método open() admiten un segundo parámetro relativo al modo. Este argumento describe si la conexión se abre para lectura, escritura o para ambas operaciones. En la clase Connector se definen las siguientes constantes a usar como valores posibles para este parámetro: READ, WRITE y READ_WRITE.
En el caso de la primera versión del método, donde no aparece este argumento, se abrirá una conexión tanto para lectura como para escritura. La última versión del método consta de un único argumento que permite especificar el tiempo límite de espera a establecimiento de la conexión. Si este tiempo se sobrepasa se lanzará una excepción.
En cualquier caso, el método open() devuelve un objeto de la clase Connection, que es la interfaz base de todos los tipos de conexión disponibles. Será necesario hacer una conversión de tipos para convertir este objeto al tipo de conexión que deseemos manejar. Por ejemplo, la siguiente línea de código muestra cómo crear una conexión HTTP mediante la interfaz StreamConnection::
StreamConnection conn = (StreamConnection)Connector.open("http://poldo.ugr.es/frases.txt");
Más adelante se verá la forma de usar este flujo para poder leer datos.
La clase Connector y los interfaces de conexión asociados se usan para obtener una conexión a red mediante un protocolo específico. Tras el establecimiento de la conexión deben usarse clases que permitan realizar operaciones de entrada salida de la conexión. Estas clases para realizar operaciones de E/S están contenidas en el paquete java.io y son:
Estas clases son similares a las usadas para entrada salida en la plataforma estándar de Java. A continuación se explica cómo usar estas clases para hacer operaciones de entrada y salida. Quizás las clases más importantes sean InputStream y OutputStream, ya que proporcionan la funcionalidad básica de E/S con flujos de datos.
La clase InputStream es una clase abstracta que sirve como clase base para las otras clases de flujos de entrada de MIDP. Esta clase define una interfaz básica para lectura de información de un flujo. El escenario típico de uso de los flujos de entrada consiste en crear un objeto de esta clase a partir de una conexión y después indicar que se desea leer información invocando al método read(). Si no hay información de entrada disponible, entonces el flujo de entrada usa una técnica conocida como bloqueo para esperar hasta la llegada de datos.
Un ejemplo de bloqueo se presenta en el caso de usar un flujo de entrada para leer información de una conexión HTTP. Hasta que el servidor Web no entregue la información no habrá entrada disponible para el objeto de la clase InputStream que hayamos creado. De esta forma. el objeto espera (se bloquea) hasta disponer de información, momento en el que la información se procesa como datos de entrada.
La clase InputStream define los métodos siguientes:
Como se aprecia, hay tres versiones diferentes del método de lectura. El primer método carece de argumentos y simplemente lee un byte de datos del flujo y devuelve un valor entero. Este versión devuelve el valor -1 si se alcanza el final del flujo de entrada. Al devolverse un entero será necesario hacer una conversión a carácter (char) en el caso de leer caracteres.
La segunda versión de read() tiene un array de bytes como único argumento. Esto permite leer varios bytes de datos a la vez, almacenándose los datos leidos en el array. Este método devuelve el número de bytes leidos o bien -1 en caso de alcanzar el final del flujo.
La última versión de read() es similar a la segunda, pero permite especificar las posiciones del array en que se almacenarán los datos leidos. El parámetro off especifica el desplazamiento respecto al inicio del array del lugar de comienzo de almacenamiento. El parámetro len especifica el máximo número de bytes a leer.
El método skip() se usa para saltar bytes del flujo de entrada. El argumento de este método indicará cuántos bytes hay que saltar (ignorar). Devuelve el número de bytes saltados o bien -1 en caso de alcanzarse el final del flujo.
El método available() se usa para determinar el número de bytes de datos de entrada que pueden leerse sin bloquearse. Este méetodo no usa parámetros y devuelve el número de datos disponibles. El método es útil si desea asegurar que hay datos de entrada disponibles antes de llamar al método read() y evitar así el bloqueo.
El método mark() marca la posición actual del flujo. Posteriormente puede volver a esta posición usando el método reset(). Estos métodos son útiles en casos en que se desea leer datos por adelantado, siendo necesario recordar la posición inicial. El método mark() precisa un argumento que especifica el número de bytes que pueden leerse antes de que la marca quede invalidada. Es decir, indica cuántos bytes pueden leerse hacia adelante antes de poder volver atrás. El método markSupported() devulve un valor booleano que indica si un flujo de entrada admite la funcionalidad de establecimiento de marca.
Finalmente, el método close() cierra un flujo de entrada y libera los recursos asociados con el flujo. No es necesario llamar explícitamente al método close() ya que los flujos de entrada se cierran automáticamente al destruirse los objetos de la clase InputStream.
La clase OutputStream es la clase de salida equivalente a InputStream, pero ahora para salida de datos. Sirve como clase base abstracta para todos los flujos de salida de MIDP. Esta clase define el protolo básico para escribir datos en flujos de salida. El uso típico consistirá en crear un objeto de esta clase a partir de la conexión y después llamar al método write() para indicar que se desea escribir información. Esta clase utiliza la técnica de bloqueo similar a la usada por InputStream: el flujo se bloquea hasta haber escrito datos en un dispositivo de salida. Mientras está bloqueado no se admiten nuevas operaciones de escritura. Los métodos soportados por esta clase son los siguientes:
De forma similar a como ocurría con la clase InputStream, esta clase define tres métodos write() diferentes. El primero de ellos escribe un byte en el flujo. Este byte está especificado por el argumento b. La segunda versión de write() toma como argumento un array de bytes, que se escribirán al flujo de salida. La última versión usa tres argumentos: un array, un desplazamiento y una longitud. Es similar a la segunda versión, pero en este caso se define la posición del array a partir de donde empezará la escritura en el flujo y el número de bytes que habrán de enviarse al mismo.
El método flush() se usa para forzar el envío de los datos al flujo.
Por último, el método close() cierra el flujo de salida y libera los recursos que pudieran estar usándose. Como ocurría en el caso de la clase InputStream, no es preciso el cierre explícito del flujo de salida, ya que la destrucción de los objetos de esta clase implica realizar esta operación.
Tras esta presentación de los aspectos generales de las conexiones a red mediante MIDP y de las clases necesarias para hacer entrada/salida, hay que conjugar ambas cosas para realizar una conexión de red. Esto es más fácil de lo que en principio pudiera parecer. La realización de la conexión consta de los tres pasos básicos indicados a continuación:
Esto es todo lo necesario. Obviamente, lo realmente importante es lo que luego se hace con los datos enviados, pero esto forma parte de la aplicación a realizar y no tiene que ver con lo considerado en este tema de conexión a redes. A continuación se explicará cómo se realizan los tres pasos básicos descritos previamente.
El primer paso necesario consiste en establacer la conexión de red. Esto se consigue mediante el método open() de la clase Connector. La forma más sencilla de este método precisa el uso de un parámetro: la cadena de conexión. El siguiente ejemplo muestra cómo abrir un flujo en una conexión HTTP a una página Web:
StreamConnection conexion = null;
// Como argumento se pasa la dirección URL a acceder
conexion=(StreamConnection)Connector.open("http://www.ugr.es");
El siguiente paso consiste en obtener un flujo de entrada y salida a partir de la conexión. Esto es necesario para poder realizar operaciones de entrada y salida.
Obtener un flujo de entrada es muy sencillo. El código necesario aparece a continuación:
InputStream entrada=conexion.openInputStream();
El método openInputStream() es todo lo que se necesita para obtener el flujo de entrada de la conexión. Una vez obtenido el flujo, puede usarse para leer datos de la conexión HTTP.
Antes se ha comentado que el método read() es el necesario para poder leer datos de un flujo de entrada. La versión más básica del método lee un byte de entrada, devolviendo su valor como un entero. Las llamadas sucesivas irán devolviendo bytes adicionales de la entrada. La lectura debería seguir hasta agotar los datos disponibles en el flujo (es decir, hasta que una operación de lectura devuelva -1). A continuación se muestra un ejemplo de cómo se haría esto, utilizando un bucle de lectura que muestra por la consola lo que se va leyendo:
StringBuffer datos = new StringBuffer();
// Bucle de lectura hasta que no haya mas datos disponibles
while ((ch = entrada.read()) != -1) {
if (ch != '\n') {
// Se lee una linea completa: hasta salto de linea
datos.append((char)ch);
}
else{
// Ha finalizado la linea y se muestra
System.out.println(datos.toString());
// Se limpia el buffer de datos para preparar la lectura
// de nuevas lineas
datos = new StringBuffer();
}
}
En este código la variable datos en un búfer de cadenas de caracteres para mantener una línea de datos cada vez. El método read() se utiliza para ir leyendo caracteres hasta alcanzar el salto de línea. Cuando se alcanza el fin de línea se presenta por pantalla y se limpia el buffer para preparar la recepción de una nueva línea.
Este código representa la premisa básica de cómo deberían leerse datos de un flujo de entrada definido sobre una conexión HTTP. Si se tiene en cuenta la gran cantidad de datos disponibles en páginas Web, la pàrte realmente complicada radica en analizar el texto recibido a través del flujo de entrada para extraer la información necesaria. Se verán algunos ejemplos de cómo hacer esto.
El MIDlet que realizaremos a continuación tiene como objetivo poner en práctica los conocimientos vistos hasta ahora. Nuestro MIDlet se llamará Frases y tiene como objetivo leer y mostrar, de forma aleatoria, frases localizadas en un archivo ubicado en un servidor Web remoto. Este MIDlet usará una conexión HTTP para abrir el archivo de texto y poder leer de él. El contenido del archivo se volcará en un vector de cadenas de caracteres. Posteriormente, se seleccionará de forma aleatoria una de las frases y se mostrará por pantalla.
La función básica del MIDlet es establecer una conexión de red y leer líneas de un archivo de texto ubicado en un servidor Web. El archivo de texto debe, por tanto, poder abrirse en un navegador Web poniendo su dirección completa.
El archivo de texto ubicado en http://poldo.ugr.es se denomina frases.txt y su contenido es el siguiente:
Aprendemos de la historia que realmente no aprendemos de la historia. Las leyes mezquinas producen grandes crímenes. El derecho a estar solo es el comienzo de toda libertad. Entre amigos, ¿qué es la Constitución?. El mejor resultado de la educación es la tolerancia. La tiranía siempre se organiza mejor que la libertad.
Cada frase del archivo debe aparecer en una línea aparte. Esto es necesario porque el MIDlet procesará las líneas una a una. Esto facilita el análisis del texto. Para conseguir la funcionalidad deseada dividiremos el código del MIDlet en los siguientes componentes:
Al ejecutar este MIDlet por primera vez se recupera el texto completo del archivo. Posteriormente se irán seleccionando las frases de forma aleatoria. La selección se hace al activar el comando Siguiente. Sólo se precisa un comando más, Salir, con el que finaliza la ejecución del MIDlet. Estos comandos se crean como datos miembros de la clase Frases, junto con los elementos de la interfaz de usuario del MIDlet, la cadena de caracteres que almacena la frase actualmente seleccionada, el vector de cadenas necesario para almacenar el contenido del archivo y una variable booleana para controlar si se trata de la primea vez que se llama al método startApp().
// Comandos de gestion del MIDlet private Command comandoSalir, comandoSiguiente; // Display del dispositivo movil private Display display; // Formulario para posicionar los elementos de // la aplicacion private Form formulario; // Para almacenar la frase seleccionada private StringItem frase; // Vector para guardar todas las frases private Vector frases; // Variable booleana para controlar la ejecucion // de startApp la primera vez y en sucesivas // llamadas despues de cada pausa private boolean primeraVez;
Como se aprecia, en primer lugar se definen los comandos necesarios: comandoSalir y comandoSiguiente. El objeto display se usará para conseguir mostrar cosas en la pantalla del terminal móvil. El objeto formulario, de la clase Form, se precisa para que contenga la frase seleccionada en cada momento. En este contenedor se mostrará el contenido de la frase seleccionada, que estará almacenada en el objeto frase, de la clase StringItem. Finalmente, se declara el vector frases usado para contener todas las frases del archivo. Para poder usar objetos de la clase Vector es necesario importar la clase (se consigue mediante la sentencia import java.util.Vector;). A continuación se muestran las líneas a incluir en el constructor de la clase:
// Constructor de la clase Frases. Inicializa los datos
// miembros
public Frases() {
// Se obtiene una referencia al display
display = Display.getDisplay(this);
// Se crean los comandos
comandoSalir=new Command("Salir", Command.EXIT, 2);
comandoSiguiente = new Command("Siguiente", Command.OK, 2);
// Se crea el formulario
formulario = new Form("Frase del día");
// Se crea el StringItem para contener la frase seleccionada
frase = new StringItem("", "Leyendo frases...");
// Se agrega el objeto al formulario
formulario.append(frase);
// Se establecen los comandos al formulario
formulario.addCommand(comandoSalir);
formulario.addCommand(comandoSiguiente);
// Se agrega un gestor de eventos para atender a los comandos
formulario.setCommandListener(this);
// Se crea el vector de frases
frases = new Vector();
// Se inicializa primeraVez a true
primeraVez=true;
}
El código del método startApp(). Siguiendo las indicaciones vistas previamente, se prepara el método para la posible ocurrencia de eventos de pausa. A tal efecto se incluyó el dato miembro primeraVez.
// Se inicia la ejecucion del MIDlet y se muestra la primera de las frases
public void startApp() throws MIDletStateChangeException {
// Mostrar el formulario y leer las frases solo se hara la primera
// vez
if (primeraVez == true){
// Se muestra el formulario por pantalla
display.setCurrent(formulario);
// Se leen las frases
leerFrases();
// Se hace que primeraVez sea false
primeraVez=false;
}
// Sea o no la primera vez, se selecciona aleatoriamente
// una frase y se muestra
mostrarFrase();
}
La gestión de comandos se realiza en el método commandAction(), cuyo código se incluye a continuación:
// Método de gestión de los comandos
public void commandAction(Command c, Displayable s) {
// Si se trata del comando salir se llama de destroyApp()
if (c == comandoSalir) {
// Se llama con argumento false para controlar la
// posible solicitud de salida mientras se esta
// leyendo el archivo
destroyApp(false);
// Se indica al dispositivo que se desea finalizar
notifyDestroyed();
}
else if (c == comandoSiguiente) {
// Mostrar de forma aleatoria la siguiente frase
mostrarFrase();
}
}
La funcionalidad de red de este MIDlet se encuentra dentro del método leerFrases(). Recordad que los pasos básicos necesarios son:
Los puntos 2 y 3 se realizan mediante un bucle while que realiza la lectura hasta alcanzar el final del archivo. A continuación se incluye el código comentado del método leerFrases():
// Método que lee las frases del archivo del servidor web
private void leerFrases() {
StreamConnection conexion = null;
InputStream entrada = null;
StringBuffer datos = new StringBuffer();
// Se procede a realizar la conexion
try {
// Se abre la conexión HTTP
conexion=(StreamConnection)Connector.open("http://poldo.ugr.es/frases.txt");
// Se obtiene un flujo de entrada a partir de la conexión
entrada = conexion.openInputStream();
// Se leen lineas del flujo de entrada
int ch;
boolean hecho = false;
while ((ch = entrada.read()) != -1) {
if (ch != '\n') {
// La linea se lee caracter a caracter
datos.append((char)ch);
}
else {
// Se agrega la frase al vector de frases
frases.addElement(datos.toString());
// Se limpia el StringBuffer
datos = new StringBuffer();
}
}
}
// Se recoge la excepcion, si se produjera
catch (IOException e) {
// En caso de producirse error, se muestra el mensaje por la pantalla
System.err.println("No pudo establecerse la conexión.");
}
}
Quedarí por programar el método que selecciona al azar una frase y la muestra por pantalla:
// El metodo mostrarFrase selecciona frase al azar y la muestra por pantalla
private void mostrarFrase() {
// Se comprueba que el vector de frases no esté vacío
if (!frases.isEmpty()) {
// Se crea el generador de números aleatorios. Se inicializa a
// partir de la fecha y hora actual
Random generador = new Random(Calendar.getInstance().getTime().getTime());
// Se selecciona frase al azar. El número generado estará entre 0 y
// el tamaño del vector -1 (que es el índice de la última posición)
int numeroFrase = Math.abs(generador.nextInt()) % frases.size();
// Se muestra la frase seleccionada
frase.setText((String)frases.elementAt(numeroFrase));
}
else
frase.setText("No hay frases disponibles!");
}
Resumen
En esta parte se han introducido los conceptos básicos sobre conexión de redes. De ahora en adelante se considera la construcción de un MIDlet capaz de recuperar y mostrar las condiciones meteorológicas de un determinado lugar. No hay ninguna razón especial para elegir este problema y podría haberse trabajado con cualquier otra fuente de información soportada en la Web.
Una de las aplicaciones más interesantes de J2ME consiste en recuperar datos de Internet y hacerlos disponibles a los usuarios. Una de estas aplicaciones consistiría en obtener información meteorológica mediante el teléfono móvil. Este será el objetivo de esta sección: construir un MIDlet que pueda realizar esta función. Las acciones básicas que el MIDlet debe realizar son:
En la red existen diversos sitios Web que ofrecen información meteorológica en tiempo real. En la mayoría de estos sitios se introduce el nombre de una ciudad o un código postal y se ofrece la información relativa a dicha zona geográfica.
Sin embargo, al pensar en acceder a esta información desde un dispositivo móvil surgen varios problemas. En primer lugar, ¿;cómo actuar sobre la página Web para solicitar información sobre una determinada ciudad? Y en segundo lugar, ¿cómo visualizar la información de la página sobre la pantalla del dispositivo móvil?
Nota:
Para visualizar información meteorológica en un MIDlet es preciso encontrar un origen de los datos (una página Web) con el formato adecuado para poder leer y analizar. Uno de estos sitios es, por ejemplo, http://iwin.nws.noaa.gov/. En este sitio la información se ofrece en un formato simple fácil de analizar y mostrar. Es decir, resulta relativamente sencillo leer la página con los datos solicitados y analizarla para extraer la información de interés. Como la pantalla de los dispositivos móviles es limitada hay que filtrar la información recibida de la página Web antes de mostrarla.
La página web con información meteorológica está bien organizada y está en un formato fácil de acceder. Hemos de pensar en la forma de obtener la información deseada. Jugando un poco con la página vemos que la información de Nueva York se encuentra en la página: http://iwin.nws.noaa.gov/iwin/ny/hourly.html. Esta información URL incluye la dirección base (http://iwin.nws.noaa.gov/) y un par de directorios adicionales que se refieren a la información en la que estamos interesados (iwin/ny/). Finalmente, sigue la página en sí que deseamos recuperar: hourly.html.
Es decir, la información sobre los diferentes estados se organiza en directorios diferentes, de forma que si queremos acceder a la información sobre un determinado estado sólo hemos de modificar las dos letras relativas al estado: en este caso ny. Por ejemplo, si se desea acceder a la información meteorológica sobre Arizona la dirección a usar será: http://iwin.nws.noaa.gov/iwin/az/hourly.html. En realidad, la cadena que indica la dirección a acceder podría descomponerse de la forma siguiente:
String direccion="http://iwin.nws.noaa.gov/iwin/"+estado+"/hourly.html";
La variable estado indicaría las dos letras que identifican a cada uno de los estados.
Conviene ahora prestar atención a la información mostrada en la página de un estado cualquiera. En verdad, aunque parece que su contenido es texto únicamente, se trata de información ubicada en una página web, por lo que está codificada mediante HTML. Por tanto, habrá que ignorar las etiquetas de HTML para acceder a los datos reales. La página de un estado cualquiera sería la siguiente:
New York - Hourly data
NOAA's NWS will be accepting comments on proposed IWIN replacement pages until April 30, 2006. Please learn more about the replacement and how to leave a comment here |
ASUS41 KPHI 030810
RWRPHI
REGIONAL WEATHER ROUNDUP
NATIONAL WEATHER SERVICE MOUNT HOLLY NJ
400 AM EDT TUE OCT 03 2006
NOTE: "FAIR" INDICATES FEW OR NO CLOUDS BELOW 12,000 FEET WITH NO
SIGNIFICANT WEATHER AND/OR OBSTRUCTIONS TO VISIBILITY.
* = STATION DOES NOT REPORT PRECIPITATION (E.G. RAIN, SNOW, ETC.)
OR FOG.
NJZ015>026-030900-
SOUTHERN NEW JERSEY
CITY SKY/WX TMP DP RH WIND PRES REMARKS
POMONA PTCLDY 54 49 83 CALM 30.22S
TRENTON CLOUDY 51 48 89 CALM 30.20S
$$
NJZ001>014-030900-
NORTHERN NEW JERSEY
CITY SKY/WX TMP DP RH WIND PRES REMARKS
SUSSEX CLEAR 45 44 97 CALM 30.20F
ANDOVER N/A 46 45 96 CALM 30.20S
NEWARK PTCLDY 55 47 74 W6 30.19S
TETERBORO PTCLDY 53 47 79 CALM 30.18F
CALDWELL PTCLDY 48 47 96 CALM 30.20S
SOMERVILLE PTCLDY 47 45 93 CALM 30.19S
$$
PAZ043-044-047-054-055-060>062-066>071-030900-
EASTERN PENNSYLVANIA
CITY SKY/WX TMP DP RH WIND PRES REMARKS
PHILADELPHIA NOT AVBL
LANCASTER CLOUDY 57 54 89 CALM 30.19F
ALLENTOWN CLOUDY 52 48 86 CALM 30.19F
MOUNT POCONO CLOUDY 49 45 86 VRB3 30.20F
WILKES BARRE PTCLDY 50 47 89 SE5 30.18F
$$
DEZALL-MDZ008-012-015-019-020-030900-
DELAWARE AND EASTERN MARYLAND
CITY SKY/WX TMP DP RH WIND PRES REMARKS
WILMINGTON CLOUDY 59 55 87 CALM 30.20S
PATUXENT MOCLDY 62 56 80 SW3 30.21S
OCEAN CITY PTCLDY 58 56 93 W3 30.22R
WALLOPS ISLAND PTCLDY 57 53 86 CALM 30.22S
$$
PAZ001-021-NYZ056-072-MDZ011-DCZ001-030900-
OTHER NEARBY LOCATIONS
CITY SKY/WX TMP DP RH WIND PRES REMARKS
BINGHAMTON CLEAR 53 47 79 S6 30.16F
NEW YORK CITY PTCLDY 58 50 75 CALM 30.21F
BALTIMORE NOT AVBL
WASHINGTON DC LGT RAIN 64 59 83 SE7 30.20F
$$
|
ASUS41 KOKX 030810
RWROKX
REGIONAL WEATHER ROUNDUP
NATIONAL WEATHER SERVICE UPTON NY
400 AM EDT TUE OCT 03 2006
NOTE: "FAIR" INDICATES FEW OR NO CLOUDS BELOW 12,000 FEET WITH NO
SIGNIFICANT WEATHER AND/OR OBSTRUCTIONS TO VISIBILITY.
NYZ071-072-076-NJZ005-030900-
NEW YORK CITY METRO AREA
CITY SKY/WX TMP DP RH WIND PRES REMARKS
CENTRAL PARK PTCLDY 58 50 75 CALM 30.21F
LAGUARDIA APRT PTCLDY 60 49 66 CALM 30.18S
KENNEDY INTL PTCLDY 53 50 89 CALM 30.19F
NEWARK/LIBERTY PTCLDY 55 47 74 W6 30.19S
WHITE PLAINS NOT AVBL
$$
NYZ077>081-030900-
LONG ISLAND NEW YORK
CITY SKY/WX TMP DP RH WIND PRES REMARKS
FARMINGDALE CLEAR 52 48 86 CALM 30.19S
ISLIP NOT AVBL
SHIRLEY NOT AVBL
WESTHAMPTON CLEAR 42 39 89 CALM 30.20S
MONTAUK POINT N/A 52 48 86 CALM 30.20R
$$
NYZ052-065-067-030900-
HUDSON VALLEY
CITY SKY/WX TMP DP RH WIND PRES REMARKS
NEWBURGH NOT AVBL
MONTGOMERY NOT AVBL
POUGHKEEPSIE PTCLDY 45 45 100 CALM 30.17F
ALBANY PTCLDY 50 47 89 S6 30.15F
$$
NJZ001-003-005-008-013-015-019-021-022-030900-
NEW JERSEY
CITY SKY/WX TMP DP RH WIND PRES REMARKS
TETERBORO PTCLDY 53 47 79 CALM 30.18F
CALDWELL PTCLDY 48 47 96 CALM 30.20S
SOMERVILLE PTCLDY 47 45 93 CALM 30.19S
ANDOVER N/A 46 45 96 CALM 30.20S
TRENTON CLOUDY 51 48 89 CALM 30.20S
MILLVILLE NOT AVBL
WRIGHTSTOWN NOT AVBL
BELMAR NOT AVBL
$$
PAZ047>061-062-071-030900-
EASTERN PENNSYLVANIA
CITY SKY/WX TMP DP RH WIND PRES REMARKS
PHILADELPHIA NOT AVBL
ALLENTOWN CLOUDY 52 48 86 CALM 30.19F
SCRANTON NOT AVBL
$$
CTZ002-004>006-009-010-012-RIZ004-006-007-MAZ004-011-015-030900-
SOUTHERN NEW ENGLAND
IN CT
CITY SKY/WX TMP DP RH WIND PRES REMARKS
BRADLEY INTL CLEAR 47 45 93 CALM 30.17S
HARTFORD CLEAR 49 47 93 CALM 30.18S
DANBURY CLEAR 44 43 96 CALM 30.20F
WTRBRY/OXFORD NOT AVBL
BRIDGEPORT CLEAR 49 45 86 CALM 30.18F
MERIDEN CLEAR 45 43 93 CALM 30.19R
NEW HAVEN CLEAR 47 45 93 CALM 30.18S
GROTON NOT AVBL
WILLIMANTIC FOG 45 44 97 CALM 30.19R VSB 1/4
IN RI
CITY SKY/WX TMP DP RH WIND PRES REMARKS
PROVIDENCE PTCLDY 48 46 93 SW5 30.17S
BLOCK ISLAND NOT AVBL
WESTERLY CLEAR 46 44 93 CALM 30.19R
IN MA
CITY SKY/WX TMP DP RH WIND PRES REMARKS
BOSTON NOT AVBL
WORCESTER NOT AVBL
WESTFIELD MOCLDY 45 44 97 CALM 30.17S
PROVINCETOWN NOT AVBL
NANTUCKET CLEAR 50 47 89 CALM 30.17R
$$
ANZ350-353-355-338-335-330-030900-
COASTAL MARINE OBSERVATIONS
STATION/POSITION TIME SKY/WX TEMP WIND PRES VSBY WAVE
AIR SEA DIR/SP/G HT/PER
(UTC) (F) (DEG/KT/KT) (MB) (MI) (FT/S)
AMBROSE LIGHT 0700 63 66 250/ 3/ 4 1022.9
BUOY 20S FIRE IS 0700 65 65 220/ 4/ 6 1022.2 3/13
BUOY 23SW MTP 0700 64 64 290/ 8/ 8 1022.0 3/12
CENTRAL LI SOUND 0700 63 67 300/ 10/ 14 1022.1
ROBBINS REEF 0700 58 270/ 6/ 7 1023.2
$$
>>>>>>>>>>>>>>>>>>>>>>>>>>>> KEY <<<<<<<<<<<<<<<<<<<<<<<<<<<
> <
> SKY/WX - SKY CONDITION/PRESENT WEATHER <
> TMP - TEMPERATURE IN FAHRENHEIT <
> DP - DEWPOINT IN FAHRENHEIT <
> RH - RELATIVE HUMIDITY IN PERCENT <
> WIND - DIRECTION AND SPEED IN MPH <
> PRES - MEAN SEA LEVEL PRESSURE IN INCHES OF HG <
> WCI - WIND CHILL INDEX <
> VSB - VISIBILITY IN MILES <
> HX - HEAT INDEX <
> TC - TEMPERATURE IN CELSIUS <
> VRB - VARIABLE WIND DIRECTION <
> <
>>>>>>>>>>>>>>>>>>>>>>>>>>>> KEY <<<<<<<<<<<<<<<<<<<<<<<<<<<
|
ASUS41 KALY 030810
RWRALY
NEW YORK STATE HOURLY WEATHER ROUNDUP
NATIONAL WEATHER SERVICE ALBANY NY
400 AM EDT TUE OCT 03 2006
NOTE: "FAIR" INDICATES FEW OR NO CLOUDS BELOW 12,000 FEET WITH NO
SIGNIFICANT WEATHER AND/OR NO OBSTRUCTIONS TO VISIBILITY.
NYZ032-033-038>043-046>054-057>066-NYZ062>081-030900-
EAST
CITY SKY/WX TMP DP RH WIND PRES REMARKS
ALBANY PTCLDY 50 47 89 S6 30.15F
GLENS FALLS NOT AVBL
POUGHKEEPSIE PTCLDY 45 45 100 CALM 30.17F
NEW YORK CITY PTCLDY 60 49 66 CALM 30.18S
CENTRAL PARK PTCLDY 58 50 75 CALM 30.21F
$$
NYZ005>009-017-018-044>046-055-056-030900-
CENTRAL
CITY SKY/WX TMP DP RH WIND PRES REMARKS
SYRACUSE PTCLDY 47 45 93 E5 30.10F
UTICA NOT AVBL
ELMIRA MOCLDY 43 43 100 CALM 30.14R FOG
BINGHAMTON CLEAR 53 47 79 S6 30.16F
$$
NYZ026>034-041>043-030900-
NORTH
CITY SKY/WX TMP DP RH WIND PRES REMARKS
WATERTOWN NOT AVBL
FORT DRUM NOT AVBL
MASSENA CLEAR 44 42 93 CALM 30.04F
SARANAC LAKE PTCLDY 37 35 92 CALM 30.09F
PLATTSBURGH CLOUDY 47 45 93 CALM 30.10S
$$
NYZ001>004-010>016-019>021-030900-
WEST
CITY SKY/WX TMP DP RH WIND PRES REMARKS
NIAGARA FALLS CLEAR 63 57 81 S12 N/A
BUFFALO CLEAR 60 54 80 S7 30.04F
DUNKIRK MOCLDY 65 55 70 S12 30.05F
ROCHESTER PTCLDY 57 54 89 S5 30.07R
PENN YAN CLEAR 55 51 86 SW7 30.10F
$$
KEY
WCI = WIND CHILL INDEX
VSB = VISIBILITY
HX = HEAT INDEX
$$
|
ASUS41 KBOX 030810
RWRBOX
REGIONAL WEATHER ROUNDUP
NATIONAL WEATHER SERVICE TAUNTON MA
400 AM EDT TUE OCT 03 2006
NOTE: "FAIR" INDICATES FEW OR NO CLOUDS BELOW 12,000 FEET WITH NO
SIGNIFICANT WEATHER AND/OR OBSTRUCTIONS TO VISIBILITY. THE FOLLOWING
OBSERVATION LOCATIONS DO NOT REPORT PRESENT WEATHER...PROVINCETOWN...
SMITHFIELD...BLOCK ISLAND...KEENE...AND OXFORD.
MAZALL-030900-
EASTERN MASSACHUSETTS
CITY SKY/WX TMP DP RH WIND PRES REMARKS
BOSTON NOT AVBL
BEVERLY CLEAR 45 43 93 CALM 30.15F
LAWRENCE NOT AVBL
BEDFORD NOT AVBL
BLUE HILL N/A 52 46 80 SW8 30.15S
NORWOOD PTCLDY 38 38 100 CALM 30.16S FOG
MARSHFIELD NOT AVBL
PLYMOUTH NOT AVBL
TAUNTON CLEAR 41 40 96 CALM 30.15S FOG
NEW BEDFORD CLEAR 42 40 92 CALM 30.16S FOG
$$
MAZALL-030900-
CAPE COD AND THE ISLANDS
CITY SKY/WX TMP DP RH WIND PRES REMARKS
FALMOUTH NOT AVBL
HYANNIS NOT AVBL
CHATHAM CLEAR 51 48 89 CALM 30.17R
NANTUCKET CLEAR 50 47 89 CALM 30.17R
MARTHAS VNYRD CLEAR 40 37 89 CALM 30.17S
$$
MAZALL-030900-
CENTRAL AND WESTERN MASSACHUSETTS
CITY SKY/WX TMP DP RH WIND PRES REMARKS
WORCESTER NOT AVBL
FITCHBURG MOCLDY 44 42 93 CALM 30.17S
ORANGE FOG 44 44 100 CALM 30.17R VSB 1/4
SPRINGFIELD NOT AVBL
WESTFIELD MOCLDY 45 44 97 CALM 30.17S
NORTH ADAMS PTCLDY 42 42 100 CALM 30.17F FOG
$$
RIZALL-030900-
RHODE ISLAND
CITY SKY/WX TMP DP RH WIND PRES REMARKS
PROVIDENCE PTCLDY 48 46 93 SW5 30.17S
NEWPORT CLEAR 47 45 93 CALM 30.18R FOG
WESTERLY CLEAR 46 44 93 CALM 30.19R
$$
CTZALL-030900-
CONNECTICUT
CITY SKY/WX TMP DP RH WIND PRES REMARKS
BRADLEY INTL CLEAR 47 45 93 CALM 30.17S
HARTFORD CLEAR 49 47 93 CALM 30.18S
BRIDGEPORT CLEAR 49 45 86 CALM 30.18F
DANBURY CLEAR 44 43 96 CALM 30.20F
GROTON NOT AVBL
NEW HAVEN CLEAR 47 45 93 CALM 30.18S
MERIDEN CLEAR 45 43 93 CALM 30.19R
WILLIMANTIC FOG 45 44 97 CALM 30.19R VSB 1/4
$$
MEZ002-015-021-024-NHZ003-005-008-011-012-014-VTZ005-008-030900-
NORTHERN NEW ENGLAND
CITY SKY/WX TMP DP RH WIND PRES REMARKS
PORTLAND ME CLEAR 45 43 93 CALM 30.13S
BANGOR ME CLEAR 45 41 86 W6 30.10R
CONCORD NH CLOUDY 42 41 96 CALM 30.15F
MANCHESTER NH CLOUDY 46 43 89 CALM 30.14R
NASHUA NH MOCLDY 44 42 93 CALM 30.16S
PORTSMOUTH NH NOT AVBL
JAFFREY NH FOG 41 40 96 CALM 30.16S VSB 1/4
KEENE NH NOT AVBL
BURLINGTON VT MOCLDY 45 42 89 CALM 30.11F
MT. WASHINGTON CLOUDY 36 18 48 NW55 N/A WCI 19
$$
NYZ052-076-030900-
EASTERN NEW YORK
CITY SKY/WX TMP DP RH WIND PRES REMARKS
ALBANY PTCLDY 50 47 89 S6 30.15F
NEW YORK CITY PTCLDY 60 49 66 CALM 30.18S
$$
ANZALL-030900-
MARINE OBSERVATIONS
STATION/POSITION TIME TEMP WIND PRES VSBY WAVE
AIR SEA DIR/SP/G HT/PER
(UTC) (F) (DEG/KT/KT) (MB) (MI) (FT/S)
BOSTON BUOY 0700 55 56 240/ 4/ 6 1021.1F 3/ 7
BUZZARDS BAY 0700 57 63 60/ 2/ 3 1021.5F
SE OF CAPE COD 0700 60 62 330/ 10/ 12 1020.7S 5/ 6
S OF MONTAUK PT 0700 64 64 290/ 8/ 8 1022.0S 3/12
MASS BAY-STELLWA 0700 55 58 260/ 8/ 10 1020.5R 1 7/8 3/ 6
ISLE OF SHOALS 0700 53 260/ 9/ 10 1020.6R
$$
......................KEY.........................
SKY/WX - SKY CONDITION/PRESENT WEATHER
TMP - TEMPERATURE IN FAHRENHEIT
DWPT - DEWPOINT IN FAHRENHEIT
RH - RELATIVE HUMIDITY IN PERCENT
WIND - DIRECTION AND SPEED IN MPH
PRES - MEAN SEA LEVEL PRESSURE IN INCHES OF HG
WCI - WIND CHILL INDEX
VSB - VISIBILITY IN MILES
HX - HEAT INDEX
TC - TEMPERATURE IN CELSIUS
VRB - VARIABLE WIND DIRECTION
N/A - NOT AVAILABLE
|
ASUS41 KGYX 030808
RWRGYX
WEATHER ROUNDUP FOR MAINE AND NEW HAMPSHIRE
NATIONAL WEATHER SERVICE GRAY ME
400 AM EDT TUE OCT 03 2006
MEZ002-005-006-010-012-015-018-020-021-024-026-027-029-030900-
MAINE
CITY SKY/WX TMP DP RH WIND PRES REMARKS
PORTLAND CLEAR 45 43 93 CALM 30.13S
WISCASSET NOT AVBL
FRYEBURG FOG 39 37 93 CALM 30.13R VSB 3/4
AUGUSTA NOT AVBL
BANGOR NOT AVBL
GREENVILLE N/A 45 42 89 CALM 30.05S
MILLINOCKET NOT AVBL
HOULTON NOT AVBL
PRESQUE ISLE NOT AVBL
FRENCHVILLE NOT AVBL
CARIBOU CLOUDY 44 41 89 SW3 30.00R
$$
NHZ002-005-008-009-011-012-014-030900-
NEW HAMPSHIRE
CITY SKY/WX TMP DP RH WIND PRES REMARKS
ROCHESTER PTCLDY 46 44 93 CALM 30.14S
MANCHESTER NOT AVBL
CONCORD CLOUDY 42 41 96 CALM 30.15F
BERLIN CLOUDY 41 40 96 CALM 30.14R
WHITEFIELD FOG 41 41 100 CALM 30.15R VSB 1/4
JAFFREY NOT AVBL
LEBANON NOT AVBL
MT WASHINGTON CLOUDY 36 18 48 NW55 N/A
$$
VTZ005-007-008-030900-
VERMONT
CITY SKY/WX TMP DP RH WIND PRES REMARKS
ST JOHNSBURY N/A 44 43 96 MISG 30.14R
MONTPELIER FOG 41 39 93 CALM 30.16S VSB 1/2
BURLINGTON MOCLDY 45 42 89 CALM 30.11F
$$
MAZ007-012-024-CTZ003-RIZ002-NYZ038-NYZ072-030900-
SOUTHERN NEW ENGLAND AND NY
CITY SKY/WX TMP DP RH WIND PRES REMARKS
PROVIDENCE PTCLDY 48 46 93 SW5 30.17S
HARTFORD CLEAR 47 45 93 CALM 30.17S
ALBANY PTCLDY 50 47 89 S6 30.15F
NEW YORK CITY PTCLDY 60 49 66 CALM 30.18S
$$
ANZ081-ANZ082-ANZ150-NHZ014-MEZ023>029-030900-
COASTAL MARINE OBSERVATIONS
STATION/POSITION TIME TEMP WIND PRES WAVE
AIR SEA DIR/SP/G HT/PER
(UTC) (F) (DEG/KT/KT) (MB) (FT/S)
MATINICUS ROCK 0700 54 270/ 12/ 14 1018.6F
PORTLAND WX BUOY 0700 54 56 260/ 10/ 12 1019.3S 3/13
ISLE OF SHOALS 0700 53 260/ 9/ 10 1020.6R
CASHES LEDGE BUO 0700 56 56 N/A 3/11
GEORGES BANK BUO 0700 59 60 320/ 16/ 19 1017.4R 7/ 7
$$
.............KEY..............
WCI - WIND CHILL
TC - TEMPERATURE IN CELSIUS
VSB - VISIBILITY IN MILES
HX - HEAT INDEX
FAIR- INDICATES FEW OR NO CLOUDS BELOW 12,000 FT, WITH NO
SIGNIFICANT WEATHER AND/OR OBSTRUCTIONS TO VISIBILITY.
|
ASUS41 KBUF 030800
RWRBUF
BUFFALO CLEAR 60/16 54 81 30.04F S 7
|
ASUS41 KPHI 030710
RWRPHI
REGIONAL WEATHER ROUNDUP
NATIONAL WEATHER SERVICE MOUNT HOLLY NJ
300 AM EDT TUE OCT 03 2006
NOTE: "FAIR" INDICATES FEW OR NO CLOUDS BELOW 12,000 FEET WITH NO
SIGNIFICANT WEATHER AND/OR OBSTRUCTIONS TO VISIBILITY.
* = STATION DOES NOT REPORT PRECIPITATION (E.G. RAIN, SNOW, ETC.)
OR FOG.
NJZ015>026-030800-
SOUTHERN NEW JERSEY
CITY SKY/WX TMP DP RH WIND PRES REMARKS
POMONA MOCLDY 52 48 86 CALM 30.22S
$$
NJZ001>014-030800-
NORTHERN NEW JERSEY
CITY SKY/WX TMP DP RH WIND PRES REMARKS
ANDOVER N/A 47 45 93 CALM 30.20S
NEWARK NOT AVBL
$$
PAZ043-044-047-054-055-060>062-066>071-030800-
EASTERN PENNSYLVANIA
CITY SKY/WX TMP DP RH WIND PRES REMARKS
PHILADELPHIA NOT AVBL
ALLENTOWN FAIR 50 47 89 NW5 30.20S
WILKES BARRE CLOUDY 50 47 89 E3 30.19S
$$
DEZALL-MDZ008-012-015-019-020-030800-
DELAWARE AND EASTERN MARYLAND
CITY SKY/WX TMP DP RH WIND PRES REMARKS
WILMINGTON NOT AVBL
PATUXENT FAIR 60 55 83 CALM 30.21R
OCEAN CITY NOT AVBL
WALLOPS ISLAND FAIR 58 53 84 CALM 30.22S
$$
PAZ001-021-NYZ056-072-MDZ011-DCZ001-030800-
OTHER NEARBY LOCATIONS
CITY SKY/WX TMP DP RH WIND PRES REMARKS
BINGHAMTON NOT AVBL
NEW YORK CITY FAIR 59 51 75 CALM 30.22R
BALTIMORE NOT AVBL
WASHINGTON DC NOT AVBL
$$
|
ASUS41 KALY 030710
RWRALY
NEW YORK STATE HOURLY WEATHER ROUNDUP
NATIONAL WEATHER SERVICE ALBANY NY
300 AM EDT TUE OCT 03 2006
NOTE: "FAIR" INDICATES FEW OR NO CLOUDS BELOW 12,000 FEET WITH NO
SIGNIFICANT WEATHER AND/OR NO OBSTRUCTIONS TO VISIBILITY.
NYZ032-033-038>043-046>054-057>066-NYZ062>081-030800-
EAST
CITY SKY/WX TMP DP RH WIND PRES REMARKS
ALBANY FAIR 48 46 93 S3 30.17R
GLENS FALLS NOT AVBL
POUGHKEEPSIE NOT AVBL
NEW YORK CITY NOT AVBL
CENTRAL PARK FAIR 59 51 75 CALM 30.22R
$$
NYZ005>009-017-018-044>046-055-056-030800-
CENTRAL
CITY SKY/WX TMP DP RH WIND PRES REMARKS
SYRACUSE FAIR 47 45 93 E6 30.11F
UTICA NOT AVBL
ELMIRA NOT AVBL
BINGHAMTON NOT AVBL
$$
NYZ026>034-041>043-030800-
NORTH
CITY SKY/WX TMP DP RH WIND PRES REMARKS
WATERTOWN NOT AVBL
FORT DRUM NOT AVBL
MASSENA NOT AVBL
$$
NYZ001>004-010>016-019>021-030800-
WEST
CITY SKY/WX TMP DP RH WIND PRES REMARKS
BUFFALO FAIR 60 53 77 SW7 30.06S
ROCHESTER MOCLDY 57 53 86 SW6 30.06F
$$
KEY
WCI = WIND CHILL INDEX
VSB = VISIBILITY
HX = HEAT INDEX
$$
|
ASUS41 KOKX 030710
RWROKX
REGIONAL WEATHER ROUNDUP
NATIONAL WEATHER SERVICE UPTON NY
300 AM EDT TUE OCT 03 2006
NOTE: "FAIR" INDICATES FEW OR NO CLOUDS BELOW 12,000 FEET WITH NO
SIGNIFICANT WEATHER AND/OR OBSTRUCTIONS TO VISIBILITY.
NYZ071-072-076-NJZ005-030800-
NEW YORK CITY METRO AREA
CITY SKY/WX TMP DP RH WIND PRES REMARKS
CENTRAL PARK FAIR 59 51 75 CALM 30.22R
LAGUARDIA APRT NOT AVBL
KENNEDY INTL NOT AVBL
NEWARK/LIBERTY NOT AVBL
WHITE PLAINS NOT AVBL
$$
NYZ077>081-030800-
LONG ISLAND NEW YORK
CITY SKY/WX TMP DP RH WIND PRES REMARKS
FARMINGDALE NOT AVBL
ISLIP NOT AVBL
SHIRLEY NOT AVBL
WESTHAMPTON NOT AVBL
MONTAUK POINT N/A 53 48 83 CALM 30.19S
$$
NYZ052-065-067-030800-
HUDSON VALLEY
CITY SKY/WX TMP DP RH WIND PRES REMARKS
NEWBURGH NOT AVBL
MONTGOMERY NOT AVBL
POUGHKEEPSIE NOT AVBL
ALBANY FAIR 48 46 93 S3 30.17R
$$
NJZ001-003-005-008-013-015-019-021-022-030800-
NEW JERSEY
CITY SKY/WX TMP DP RH WIND PRES REMARKS
TETERBORO NOT AVBL
CALDWELL NOT AVBL
SOMERVILLE NOT AVBL
ANDOVER N/A 47 45 93 CALM 30.20S
TRENTON NOT AVBL
MILLVILLE NOT AVBL
WRIGHTSTOWN NOT AVBL
BELMAR NOT AVBL
$$
PAZ047>061-062-071-030800-
EASTERN PENNSYLVANIA
CITY SKY/WX TMP DP RH WIND PRES REMARKS
PHILADELPHIA NOT AVBL
ALLENTOWN FAIR 50 47 89 NW5 30.20S
SCRANTON NOT AVBL
$$
CTZ002-004>006-009-010-012-RIZ004-006-007-MAZ004-011-015-030800-
SOUTHERN NEW ENGLAND
IN CT
CITY SKY/WX TMP DP RH WIND PRES REMARKS
BRADLEY INTL FAIR 48 46 93 CALM 30.17S
HARTFORD NOT AVBL
DANBURY NOT AVBL
WTRBRY/OXFORD NOT AVBL
BRIDGEPORT FAIR 52 46 80 CALM 30.19R
MERIDEN NOT AVBL
NEW HAVEN NOT AVBL
GROTON NOT AVBL
WILLIMANTIC NOT AVBL
IN RI
CITY SKY/WX TMP DP RH WIND PRES REMARKS
PROVIDENCE FAIR 49 46 90 W5 30.17F
BLOCK ISLAND NOT AVBL
WESTERLY NOT AVBL
IN MA
CITY SKY/WX TMP DP RH WIND PRES REMARKS
BOSTON NOT AVBL
WORCESTER NOT AVBL
WESTFIELD NOT AVBL
PROVINCETOWN NOT AVBL
NANTUCKET NOT AVBL
$$
ANZ350-353-355-338-335-330-030800-
COASTAL MARINE OBSERVATIONS
STATION/POSITION TIME SKY/WX TEMP WIND PRES VSBY WAVE
AIR SEA DIR/SP/G HT/PER
(UTC) (F) (DEG/KT/KT) (MB) (MI) (FT/S)
AMBROSE LIGHT 0600 63 66 270/ 2/ 2 1022.9
BUOY 20S FIRE IS 0600 65 65 200/ 2/ 4 1022.5 2/13
BUOY 23SW MTP 0600 64 65 290/ 6/ 8 1022.0 3/12
CENTRAL LI SOUND 0600 64 67 300/ 8/ 8 1022.1
ROBBINS REEF 0500 62 CALM 1023.0
$$
>>>>>>>>>>>>>>>>>>>>>>>>>>>> KEY <<<<<<<<<<<<<<<<<<<<<<<<<<<
> <
> SKY/WX - SKY CONDITION/PRESENT WEATHER <
> TMP - TEMPERATURE IN FAHRENHEIT <
> DP - DEWPOINT IN FAHRENHEIT <
> RH - RELATIVE HUMIDITY IN PERCENT <
> WIND - DIRECTION AND SPEED IN MPH <
> PRES - MEAN SEA LEVEL PRESSURE IN INCHES OF HG <
> WCI - WIND CHILL INDEX <
> VSB - VISIBILITY IN MILES <
> HX - HEAT INDEX <
> TC - TEMPERATURE IN CELSIUS <
> VRB - VARIABLE WIND DIRECTION <
> <
>>>>>>>>>>>>>>>>>>>>>>>>>>>> KEY <<<<<<<<<<<<<<<<<<<<<<<<<<<
|
ASUS41 KBOX 030710
RWRBOX
REGIONAL WEATHER ROUNDUP
NATIONAL WEATHER SERVICE TAUNTON MA
300 AM EDT TUE OCT 03 2006
NOTE: "FAIR" INDICATES FEW OR NO CLOUDS BELOW 12,000 FEET WITH NO
SIGNIFICANT WEATHER AND/OR OBSTRUCTIONS TO VISIBILITY. THE FOLLOWING
OBSERVATION LOCATIONS DO NOT REPORT PRESENT WEATHER...PROVINCETOWN...
SMITHFIELD...BLOCK ISLAND...KEENE...AND OXFORD.
MAZALL-030800-
EASTERN MASSACHUSETTS
CITY SKY/WX TMP DP RH WIND PRES REMARKS
BOSTON NOT AVBL
BEVERLY NOT AVBL
LAWRENCE NOT AVBL
BEDFORD NOT AVBL
BLUE HILL N/A 52 46 80 SW7 30.15S
NORWOOD NOT AVBL
MARSHFIELD NOT AVBL
PLYMOUTH NOT AVBL
TAUNTON NOT AVBL
NEW BEDFORD NOT AVBL
$$
MAZALL-030800-
CAPE COD AND THE ISLANDS
CITY SKY/WX TMP DP RH WIND PRES REMARKS
FALMOUTH NOT AVBL
HYANNIS NOT AVBL
CHATHAM NOT AVBL
NANTUCKET NOT AVBL
MARTHAS VNYRD NOT AVBL
$$
MAZALL-030800-
CENTRAL AND WESTERN MASSACHUSETTS
CITY SKY/WX TMP DP RH WIND PRES REMARKS
WORCESTER NOT AVBL
FITCHBURG NOT AVBL
ORANGE NOT AVBL
SPRINGFIELD NOT AVBL
WESTFIELD NOT AVBL
NORTH ADAMS NOT AVBL
$$
RIZALL-030800-
RHODE ISLAND
CITY SKY/WX TMP DP RH WIND PRES REMARKS
PROVIDENCE FAIR 49 46 90 W5 30.17F
NEWPORT NOT AVBL
WESTERLY NOT AVBL
$$
CTZALL-030800-
CONNECTICUT
CITY SKY/WX TMP DP RH WIND PRES REMARKS
BRADLEY INTL FAIR 48 46 93 CALM 30.17S
HARTFORD NOT AVBL
BRIDGEPORT FAIR 52 46 80 CALM 30.19R
GROTON NOT AVBL
NEW HAVEN NOT AVBL
MERIDEN NOT AVBL
WILLIMANTIC NOT AVBL
$$
MEZ002-015-021-024-NHZ003-005-008-011-012-014-VTZ005-008-030800-
NORTHERN NEW ENGLAND
CITY SKY/WX TMP DP RH WIND PRES REMARKS
PORTLAND ME NOT AVBL
BANGOR ME NOT AVBL
CONCORD NH FOG 39 39 100 CALM 30.15F VSB 3/4
MANCHESTER NH NOT AVBL
NASHUA NH NOT AVBL
PORTSMOUTH NH NOT AVBL
JAFFREY NH NOT AVBL
KEENE NH NOT AVBL
BURLINGTON VT FAIR 45 43 93 CALM 30.13R
MT. WASHINGTON CLOUDY 37 19 48 NW52 N/A WCI 22
$$
NYZ052-076-030800-
EASTERN NEW YORK
CITY SKY/WX TMP DP RH WIND PRES REMARKS
ALBANY FAIR 48 46 93 S3 30.17R
NEW YORK CITY NOT AVBL
$$
ANZALL-030800-
MARINE OBSERVATIONS
STATION/POSITION TIME TEMP WIND PRES VSBY WAVE
AIR SEA DIR/SP/G HT/PER
(UTC) (F) (DEG/KT/KT) (MB) (MI) (FT/S)
BOSTON BUOY 0600 56 57 270/ 6/ 8 1021.2R 2/ 7
BUZZARDS BAY 0600 58 63 30/ 4/ 4 1021.8R
SE OF CAPE COD 0600 60 62 340/ 12/ 14 1020.7R 5/ 6
S OF MONTAUK PT 0600 64 65 290/ 6/ 8 1022.0R 3/12
MASS BAY-STELLWA NOT AVBL
ISLE OF SHOALS 0600 53 250/ 8/ 9 1020.2S
$$
......................KEY.........................
SKY/WX - SKY CONDITION/PRESENT WEATHER
TMP - TEMPERATURE IN FAHRENHEIT
DWPT - DEWPOINT IN FAHRENHEIT
RH - RELATIVE HUMIDITY IN PERCENT
WIND - DIRECTION AND SPEED IN MPH
PRES - MEAN SEA LEVEL PRESSURE IN INCHES OF HG
WCI - WIND CHILL INDEX
VSB - VISIBILITY IN MILES
HX - HEAT INDEX
TC - TEMPERATURE IN CELSIUS
VRB - VARIABLE WIND DIRECTION
N/A - NOT AVAILABLE
|
ASUS41 KGYX 030708
RWRGYX
WEATHER ROUNDUP FOR MAINE AND NEW HAMPSHIRE
NATIONAL WEATHER SERVICE GRAY ME
300 AM EDT TUE OCT 03 2006
MEZ002-005-006-010-012-015-018-020-021-024-026-027-029-030800-
MAINE
CITY SKY/WX TMP DP RH WIND PRES REMARKS
PORTLAND NOT AVBL
WISCASSET NOT AVBL
FRYEBURG NOT AVBL
AUGUSTA NOT AVBL
BANGOR NOT AVBL
GREENVILLE N/A 44 42 93 VRB3 30.05S
MILLINOCKET NOT AVBL
HOULTON NOT AVBL
PRESQUE ISLE NOT AVBL
FRENCHVILLE NOT AVBL
CARIBOU CLOUDY 43 40 89 W5 29.99S
$$
NHZ002-005-008-009-011-012-014-030800-
NEW HAMPSHIRE
CITY SKY/WX TMP DP RH WIND PRES REMARKS
ROCHESTER NOT AVBL
MANCHESTER NOT AVBL
CONCORD FOG 39 39 100 CALM 30.15F VSB 3/4
BERLIN NOT AVBL
WHITEFIELD NOT AVBL
JAFFREY NOT AVBL
LEBANON NOT AVBL
MT WASHINGTON CLOUDY 37 19 48 NW52 N/A
$$
VTZ005-007-008-030800-
VERMONT
CITY SKY/WX TMP DP RH WIND PRES REMARKS
ST JOHNSBURY N/A 44 43 96 MISG 30.13F
BURLINGTON FAIR 45 43 93 CALM 30.13R
$$
MAZ007-012-024-CTZ003-RIZ002-NYZ038-NYZ072-030800-
SOUTHERN NEW ENGLAND AND NY
CITY SKY/WX TMP DP RH WIND PRES REMARKS
PROVIDENCE FAIR 49 46 90 W5 30.17F
HARTFORD FAIR 48 46 93 CALM 30.17S
ALBANY FAIR 48 46 93 S3 30.17R
$$
ANZ081-ANZ082-ANZ150-NHZ014-MEZ023>029-030800-
COASTAL MARINE OBSERVATIONS
STATION/POSITION TIME TEMP WIND PRES WAVE
AIR SEA DIR/SP/G HT/PER
(UTC) (F) (DEG/KT/KT) (MB) (FT/S)
MOUNT DESERT ROC 0600 53 300/ 12/ 13 1018.9R
MATINICUS ROCK 0600 54 280/ 10/ 11 1018.7R
PORTLAND WX BUOY 0600 53 56 270/ 8/ 10 1019.3S 2/14
ISLE OF SHOALS 0600 53 250/ 8/ 9 1020.2S
CASHES LEDGE BUO 0600 56 56 N/A 4/13
GEORGES BANK BUO 0600 59 60 320/ 16/ 17 1017.2R 8/ 8
$$
.............KEY..............
WCI - WIND CHILL
TC - TEMPERATURE IN CELSIUS
VSB - VISIBILITY IN MILES
HX - HEAT INDEX
FAIR- INDICATES FEW OR NO CLOUDS BELOW 12,000 FT, WITH NO
SIGNIFICANT WEATHER AND/OR OBSTRUCTIONS TO VISIBILITY.
|
ASUS41 KBUF 030700
RWRBUF
BUFFALO MAINLY CLEAR 60/16 53 78 30.06S SW 7
|
El archivo con el código html de esta página puede descargarse en el siguiente enlace: hourly.html.
El comienzo de la página contiene información no relacionada con nuestro objetivo. Mirando la parte inferior se observa que cada línea de datos comienza con el nombre de la ciudad, seguido por un conjunto de datos meteorológicos, formateados en columnas. Por tanto, para buscar la información sobre una determinada ciudad basta con encontrar la línea en que se encuentra este nombre y extraer la información necesaria. Este es el enfoque que se seguirá en este ejemplo.
La función básica del MIDlet a construir es establecer una conexión de red y recuperar el contenido de una página Web, que se analizará para buscar la información deseada, que se mostrará en la pantalla del terminal.
Para tener más control en el desarrollo de la aplicación se divide el proceso de desarrollo en tres etapas:
La interfaz de usuario
El MIDlet está diseñado de forma que el usuario debe ser capaz de introducir la ciudad y el estado del que se busca la información meteorológica. Tras obtener la información se precisa alguna forma de presentación de los datos obtenidos. Por tanto sería conveniente disponer de dos pantallas diferentes: una para gestionar la introducción de ciudad y estado y otra diferente para mostrar la información recogida de la página Web. En definitiva. el usuario introduce la ciudad y el estado y, tras pulsar un botón, se realiza la conexión para obtener el contenido de la página. Tras su análisis los resultados se presentarán en la pantalla correspondiente. Los resultados se limitan a presentar la información sobre condiciones generales, temperatura, humedad relativa, velocidad del viento y dirección. La pantalla donde se mostrará esta información se denominará pantalla de salida.
Además, será preciso disponer de varios comandos para controlar el funcionamiento de la aplicación. La pantalla de localización, donde se introduce el estado y la ciudad, precisa de un comando Ir que inicia la recuperación de datos. Como esta pantalla será, de alguna forma, la pantalla principal de la aplicación, es conveniente disponer de un comando Salir que finaliza la aplicación. Además, la pantalla de salida precisa de una comando Atrás que permita volver a la pantalla inicial.
Para realizar las pantallas se utilizan varios componentes de la interfaz de usuario que se almacenan como datos miembros del MIDlet Tiempo. La declaración de datos miembros es la siguiente:
// Definicion de los comandos private Command comandoSalir, comandoIr, comandoAtras; // Display del dispositivo movil private Display display; // Especificacion del formulario de localizacion y de los campos de texto // que se usaran en el private Form pantallaLocalizacion; private TextField campoCiudad, campoEstado; // Especificacion del formulario de condiciones y de los textos que se // mostraran en el private Form pantallaCondiciones; private StringItem localizacion, condiciones, temperatura, humedad, viento;
Por su parte, el constructor de la clase se muestra a continuación:
// Constructor de la clase Tiempo
public Tiempo() {
// Obtiene una referencia al display
display = Display.getDisplay(this);
// Se crean los comandos necesarios
comandoSalir = new Command("Salir", Command.EXIT, 2);
comandoIr = new Command("Ir", Command.OK, 2);
comandoAtras = new Command("Atras", Command.BACK, 2);
// Se crea el formulario de localizacion
pantallaLocalizacion = new Form("Introduzca localización");
// Se crea el campo de texto para introducir la ciudad
campoCiudad = new TextField("Ciudad", "", 25, TextField.ANY);
// Se agrega a la pantalla de localizacion
pantallaLocalizacion.append(campoCiudad);
// Se crea el campo de texto para introducir el estado
campoEstado = new TextField("Estado", "", 2, TextField.ANY);
// Se agrega el campo a la pantalla de localización
pantallaLocalizacion.append(campoEstado);
// Asocia los comandos de salida y de proceder a la busqueda
pantallaLocalizacion.addCommand(comandoSalir);
pantallaLocalizacion.addCommand(comandoIr);
// Se asocia a la pantalla el gestor de comandos
pantallaLocalizacion.setCommandListener(this);
// Se crea el formulario de la pantalla de condiciones
pantallaCondiciones = new Form("Condiciones actuales");
// Se crean los items de texto que apareceran en la pantalla. Se
// comienza por el de localizacion
localizacion = new StringItem("", "");
pantallaCondiciones.append(localizacion);
// Se crea el string para las condiciones
condiciones = new StringItem("", "");
pantallaCondiciones.append(condiciones);
// Lo mismo para la temperatura
temperatura = new StringItem("", "");
pantallaCondiciones.append(temperatura);
// Igual para la humedad
humedad = new StringItem("", "");
pantallaCondiciones.append(humedad);
// Igual para el viento
viento = new StringItem("", "");
pantallaCondiciones.append(viento);
// Se asocia el comando Atrás a la pantalla de condiciones
pantallaCondiciones.addCommand(comandoAtras);
pantallaCondiciones.setCommandListener(this);
}
El MIDlet que estamos construyendo consta de tres comandos: Salir, Ir y Atrás. El comando de salida ya se usó en el MIDlet previo, pero el funcionamiento de los otros dos precisa quizás algunos comentarios adicionales. El comando Ir está asociado a la pantalla de localización y es responsable de iniciar la recogida y presentación de datos meteorológicos sobre la ciudad y estado que el usuario haya introducido. El comando Atrás está asociado a la pantalla de condiciones y tiene como misión provocar que aparezca de nuevo la pantalla de localización, de forma que el usuario del MIDlet pueda volver a introducir otra ciudad y estado (o bien que se salga de aplicación). El método responsable de gestionar los comandos e implementar su funcionalidad se presenta a continuación:
// Método commandAction
public void commandAction(Command comando, Displayable pantalla) {
// Si se trata del comando salir, se sale de la aplicación. Se usa
// false como argumento
if (comando == comandoSalir) {
destroyApp(false);
notifyDestroyed();
}
// Si el comando es Ir, se procede a obtener la información
else if (comando == comandoIr) {
// Se obtiene la información para el estado y ciudad indicados
obtenerCondiciones(campoCiudad.getString().toUpperCase(), campoEstado.getString().toLowerCase());
}
// Si el comando es Atras, se vuelve a la pantalla de localizacion
else if (comando == comandoAtras) {
// Se vacían los campos de ciudad y estado
campoCiudad.setString("");
campoEstado.setString("");
// Se vuelve a la pantalla de localización
display.setCurrent(pantallaLocalizacion);
}
}
Lectura de datos
El método obtenerCondiciones() lee la ciudad y el estado especificado y procede a leer los datos meteorológicos adecuados. La dirección URL de la página a consultar incluye las iniciales del estado en minúscula. Las iniciales de la ciudad, sin embargo, han de ir en mayúscula. De ahí la llamada a las funciones pertinentes para asegurarse que al producirse la conexión web la dirección URL esté convenientemente formada.
El corazón de la aplicación, por tanto, es el método encargado de obtener las condiciones meteorológicas deseadas. Este método debe realizar las siguientes tareas:
Estos pasos pueden apreciarse en el método, cuyo listado aparece a continuación:
// Método para obtener las condiciones meteorológicas
private void obtenerCondiciones(String ciudad, String estado) {
StreamConnection conexion = null;
InputStream entrada = null;
StringBuffer datos = new StringBuffer();
// Se intenta el establecimiento de la conexion. Esto debe hacerse
// en un bloque try-catch
try {
// Se abre la conexion HTTP
conexion = (StreamConnection)Connector.open("http://iwin.nws.noaa.gov/iwin/"+estado+"/hourly.html");
System.out.println("Conexion a : http://iwin.nws.noaa.gov/iwin/"+estado+"/hourly.html");
// Se obtiene el flujo de entrada de la conexion
entrada = conexion.openInputStream();
// Se lee la entrada linea a linea
int ch;
boolean hecho = false;
// Bucle de lectura. Si se alcanza el caracter -1 indica que no hay
// mas datos
while (((char)(ch = entrada.read()) != -1) && !hecho) {
// Mientras no se lea el salto de linea
if (ch != '\n') {
// El caracter se agrega a los datos leidos
datos.append((char)ch);
}
else {
// Al ir leyendo vemos si aparece la ciudad buscada. Para que
// pueda estar, la longitud de la cadena leida debe ser al menos
// igual de larga que el nombre de la ciudad buscada
if (datos.length() >= ciudad.length()) {
// Se mira si la ciudad buscada es la primera palabra de la
// linea leida
if ((ciudad.length() > 0) &&
(datos.toString().substring(0, ciudad.length()).compareTo(ciudad) == 0)) {
// Si se ha encontrado, se escriben los datos obtenidos
localizacion.setText(ciudad + ", " + estado.toUpperCase());
// Se muestran las condiciones
condiciones.setText("Cond.: " +datos.toString().substring(15, 22));
// Se extrae la temperatura y se muestra
temperatura.setText("Temperatura: " +datos.toString().substring(25, 27) + '\260');
// Se extrae y muestra la humedad relativa
humedad.setText("Humedad Rel.: " +datos.toString().substring(33, 35) + "%");
// Se extrae y muestra la velocidad del viento
viento.setText("Viento: " +datos.toString().substring(36, 44) + " mph");
// Se muestra la pantalla de condiones
display.setCurrent(pantallaCondiciones);
// Se indica que se ha terminado, para no seguir leyendo
hecho = true;
}
}
// Se libera el string para leer los datos de la siguiente linea
datos = new StringBuffer();
}
}
// Si al llegar aqui la variable booleana hecho vale false,
// entonces se indica que hubo algun problema
if (!hecho)
display.setCurrent(new Alert("Tiempo","Localización no válida.", null, AlertType.ERROR));
}
catch (IOException e) {
System.err.println("Problema al establecer la conexión.");
}
}
Prueba del MIDlet
Tras compilar, preverificar y empaquetar el MIDlet, hay que probarlo en el emulador de Ktoolbar, por ejemplo. Para cubrir la funcionalidad siguiente se realizará el siguiente conjunto de acciones:
Ejercicio: completad el MIDlet anterior, montar el proyecto correspondiente y hacedlo funcionar.
Ejercicio: construid un MIDlet de consulta de distancias entre dos direcciones. Leed las notas siguientes para realizar este ejercicio:
Existen algunas páginas Web que permiten introducir una dirección de partida y otra de llegada y obtener la forma de alcanzar la segunda desde la primera. La idea de este ejercicio es usar estas páginas para construir un MIDlet que haga esta tarea desde un dispositivo móvil. En concreto, la página a usar es la de Microsoft MapPoint. Si se abre dicha página se obtiene una pantalla como la siguiente:
Conviene tener en cuentas las siguientes consideraciones:
Total Distance: 1.0 Kilometers Estimated Total Time: 5 minutes
Otra cosa a tener en cuenta es la posibilidad de que se produzca una redirección. Algunas veces, al teclear una dirección URL se produce un redireccionamiento directo a otra dirección distinta. Una posible forma de controlar esto sería como se indica en el siguiente fragmento de código:
// Método para realizar la conexion controlando la redireccion
private void conectar() {
HttpConnection conexion = null;
InputStream entrada = null;
StringBuffer datos = new StringBuffer();
String direccionURL="....la que sea....";
int respuesta=-1;
int ch;
System.out.println("Intento de conexion con: "+direccionURL);
// Se intenta el establecimiento de la conexion. Esto debe hacerse
// en un bloque try-catch
try {
// Se abre la conexion HTTP. Se hace bucle para volver a intentarlo
// en caso de ser necesario, de haber redireccion
while (true){
// Se intenta establecer la conexion
conexion = (HttpConnection)Connector.open(direccionURL,Connector.READ_WRITE);
// Se obtiene el codigo de respuesta a la peticion de conexion
respuesta=conexion.getResponseCode();
// Por si queremos ver la respuesta por pantalla
System.out.println("Respuesta: "+respuesta);
// Si hay redireccion, se controla
if (respuesta == HttpConnection.HTTP_TEMP_REDIRECT ||
respuesta == HttpConnection.HTTP_MOVED_TEMP ||
respuesta == HttpConnection.HTTP_MOVED_PERM) {
// Se obtiene la nueva direccion
direccionURL = conexion.getHeaderField("location");
direccionURL="http://maps.msn.com/"+direccionURL;
// Se muestra por pantalla la nueva direccion
System.out.println("Nueva direccion: "+direccionURL);
conexion.close();
}
else {
// Si se pudo conectar, se rompe el bucle
break;
}
}
// Se controla, pese a todo, si hubo algun otro error
if (respuesta != HttpConnection.HTTP_OK){
conexion.close();
System.out.println("Codigo error: "+respuesta);
// En este caso se destruye el MIDlet
destroyApp(true);
notifyDestroyed();
}
}
catch (IOException e) {
System.err.println("Problema al establecer la conexión.");
// En este caso se destruye el MIDlet
destroyApp(true);
notifyDestroyed();
}
// Si se llega aqui, la conexion esta realizada
// a la lectura de la informacion
................................
}
En las aplicaciones Web es muy usual, como hemos visto, tener que rellenar datos en un formulario para solicitar información, registro, etc. Cuando el usuario de la página pulsa sobre el botón Enviar, el contenido de la página es procesado por un programa denominado CGI (Common Gateway interface). Los CGIs residen en el servidor y tienen como objetivo leer los datos introducidos por el usuario y componer una nueva página Web que se muestra en el navegador, conteniendo, normalmente, información para el usuario (subscripción correcta, falta de datos, página de registro, etc). Este mecanismo, sin embargo, presenta varios problemas:
Estas razones originan la aparición de la tecnología servlet. De esta forma, se hace que cada ejecución se haga en una hebra (y no en un proceso aparte) y que, al mismo tiempo, se pueda controlar los privilegios de seguridad del servlet.
Desde el punto de vista de programación del dispositivo móvil, lo que interesa saber es la forma de enviar datos a un servlet, de forma que este pueda realizar su trabajo. Esto es muy similar a los ejemplos vistos anteriormente. En realidad, en el ejemplo de las distancias entre direcciones, se estaba haciendo esto. La forma de especificar la dirección URL de un servlet es:
http://host/servlet?parámetros
Hay que tener en cuenta varias consideraciones a la hora de especificar los argumentos. En primer lugar, los argumentos se separan mediante el carácter &. Los espacios en blanco deben sustituirse por el carácter +. Los caracteres alfanuméricos deben cambiarse por % seguido del número hexadecimal que representa el código del carácter a representar. Por ejemplo, si se quiere enviar como argumento S. Antonio, entonces habrá que escribir S%2e+Antonio. Esto es así ya que el número hexadecimal 2e es el código ASCII del carácter ".".
En la dirección http://sesamo.ugr.es:8080/calcAvanzada se ha instalado el servlet calculadora, cuya misión es realizar operaciones aritméticas que no pueden realizarse en el dispositivo móvil, como por ejemplo, senos y logaritmos. Los parámetros de este servlet son:
Tanto el establecimiento de la conexión como la lectura de datos se realiza de forma análoga a como se ha visto en el resto de ejemplo.