Sockets C# Basico
Sockets C# Basico
Sockets C# Basico
2.4 Sockets
Ambas formas de comunicación (UDP y TCP) utilizan la abstracción
de sockets, que proporciona los puntos extremos de la
comunicación entre procesos.
Los sockets (conectores) están presentes en la mayoría de las
versiones de UNIX, incluido Linux y también Windows.
Los sockets permiten conectar dos programas en red para que se
puedan intercambiar datos.
Los sockets están basados en una arquitectura cliente/servidor.
En esta arquitectura uno de los programas debe estar
siempre arrancado y pendiente de que alguien establezca
conexión con él. Este programa se denomina servidor.
El otro programa lo arranca el usuario cuando lo necesita y
es el programa que da el primer paso en el establecimiento
de la comunicación. Este programa se llama cliente.
El servidor, está continuamente a la
escucha y a la espera de que alguien se
quiera conectar a él.
Si hacemos una comparación con un
teléfono, un servidor es una empresa 24
horas, 365 días al año, pendiente de recibir
llamadas de sus clientes.
El cliente, en un momento dado decide conectarse a un servidor
y hacerle alguna petición.
Cuando el cliente no necesita al servidor, cierra la conexión.
En la comparativa del teléfono, el cliente es el que llama por
teléfono a la empresa cuando necesita algo de ella.
Por ejemplo, un servidor de páginas web está siempre en
marcha y a la escucha.
El navegador es el cliente. Cuando arrancamos el navegador y
ponemos la dirección del servidor web, el navegador establece
la comunicación y le pide al servidor la página web que
queremos ver. El servidor la envía y el navegador la muestra.
La comunicación entre procesos consiste en la
transmisión de un mensaje entre un conector de un
proceso y un conector de otro proceso.
Para los procesos receptores de mensajes, su
conector debe estar asociado a un puerto local y a
una de las direcciones Internet de la computadora
donde se ejecuta.
Los mensajes enviados a una dirección de Internet
y a un número de puerto concretos, sólo pueden ser
recibidos por el proceso cuyo conector esté
asociado con esa dirección y con ese puerto.
Los procesos pueden utilizar un mismo conector
tanto para enviar como para recibir mensajes. Cada
computadora permite un gran número de puertos
posibles, que pueden ser usados por los procesos
locales para recibir mensajes.
Cada proceso puede utilizar varios puertos para
recibir mensajes, pero un proceso no puede
compartir puertos con otros procesos de la misma
computadora.
Cualquier cantidad de procesos puede enviar
mensajes a un mismo puerto. Cada conector se
asocia con un protocolo concreto, que puede ser
UDP o TCP.
2.4.1 Sockets flujos (TCP)
Puerto Servicio
80 Para web con http
25 Para correo saliente con SMTP
110 Para correo entrante con POP3
119 Para el servicio de noticias con NNTP
int getPort() Devuelve el valor del puerto remoto al que está conectado
1. new
5. new Programa servidor 2. new
DatagramSocket
DatagramPacket DatagramPacket
4. new
DatagramSocket
DatagramSock DatagramSocket
et Puerto destino
6.send
3.receive
Puerto
destino
Nodo destino
import java.net.*;
public class UDPEnvia{
public static void main(String args[]){
try{
DatagramSocket MiSocket = new DatagramSocket();
byte[] buffer= new byte[15];
String Mensaje = "Hola Mundo";
buffer = Mensaje.getBytes();
DatagramPacket Paquete = new DatagramPacket(buffer,
Mensaje.length(), InetAddress.getByName("localhost"),1400);
MiSocket.send(Paquete);
MiSocket.close();
}catch (Exception exc){
System.out.println("Error");
}//try
}
}//UDPEnvia
UDPRecibe.java
import java.net.*;
public class UDPRecibe{
public static void main(String args[]){
try{
DatagramSocket MiSocket = new DatagramSocket(1400);
byte[] buffer= new byte[15];
DatagramPacket Paquete = new
DatagramPacket(buffer, buffer.length);
MiSocket.receive(Paquete);
System.out.println(new String(Paquete.getData()));
MiSocket.close();
}catch (Exception e){
System.out.println("Error");
}//try
}//main
}//UDPRecibe
Otros ejemplos de datagramas en Java
import java.net.*;
import java.io.*;
public class UDPServer{
public static void main(String args[]){
DatagramSocket aSocket = null;
try{
aSocket = new DatagramSocket(6789);
byte[] buffer = new byte[1000];
while(true){
DatagramPacket request = new DatagramPacket(buffer, buffer.length);
aSocket.receive(request);
DatagramPacket reply = new DatagramPacket(request.getData(),
request.getLength(), request.getAddress(), request.getPort());
aSocket.send(reply);
}
}catch (SocketException e){System.out.println("Socket: " + e.getMessage());
}catch (IOException e) {System.out.println("IO: " + e.getMessage());
}finally {if(aSocket != null) aSocket.close();}
}
}
Corrida:
Terminal 1
mtovar@linux-w7tc:~/programasTCP> java UDPServer
Terminal 2
mtovar@linux-w7tc:~/programasTCP> java UDPClient mireya 148.228.22.6
Reply: mireya
mtovar@linux-w7tc:~/programasTCP> java UDPClient mireya localhost
Reply: mireya
mtovar@linux-w7tc:~/programasTCP>
Configuración de las comunicaciones
DatagramPacket
Métodos Acción
InetAddress getAddress() Dirección del nodo remoto en la
comunicación
byte[] getData() Devuelve el mensaje que contiene el
datagrama
int getLength() Devuelve la longitud del mensaje del
datagrama
int getOffset() Devuelve el desplazamiento que indica el
inicio del mensaje (dentro del array de
bytes)
int getPort() Devuelve el valor del puerto remoto
void setAddress(InetAddress d) Establece el nodo remoto en la
comunicación
void setData(byte[] Mensaje) Establece el mensaje que contiene el
datagrama
Void setData(byte[] Mensaje, int Establece el mensaje que contiene el
Dezplazamiento, int Longitud) datagrama, indicando su
desplazamiento en el array de bytes y
su longitud.
Void setLength(int Longitud) Establece la longitud del mensaje del
datagrama
void setPort() Establece el valor del puerto remoto
Metódos Acción
void bind(SocketAddress a) Asigna la dirección establecida al
socket
void close() Cierra el socket
void connect(SocketAddress a) Conecta el socket a la dirección
remota establecida
void connect(InetAddress a, int Conecta el socket a la dirección
puerto) establecida y el puerto especificado
void disconnect() Desconecta el socket
InetAddress getInetAddress() Devuelve la dirección a la que está
conectada el socket.
int getLocalPort() Devuelve el número de puerto asociado al
socket
OutputStream getOutputStream() Devuelve el stream de salida asociado al socket
int getPort() Devuelve el valor del puerto remoto al que está
conectado
Int getSoTimeout() Devuelve el valor en milisegundos que el socket
espera al establecimiento de comunicación
Boolean isBound() Indica si el socket está vinculado
Boolean isClosed() Indica si el socket está cerrado
Boolean isConneted Indica si el socket está conectado
Void setSoTimeout(int ms) Indica el valor en milisegundos que el socket
espera al establecimiento de comunicación
2.4.3 Diferencias entre Sockets Stream
y Datagrama
En UDP, cada vez que se envía un datagrama, hay
que enviar también el descriptor del socket local y la
dirección del socket que va a recibir el datagrama,
luego los mensajes son más grandes que los TCP.
Como el protocolo TCP está orientado a conexión,
hay que establecer esta conexión entre los dos
sockets, lo que implica un cierto tiempo empleado
en el establecimiento de la conexión, que no es
necesario emplear en UDP.
En UDP hay un límite de tamaño de los datagramas, establecido
en 64 kilobytes, que se pueden enviar a una localización
determinada, mientras que TCP no tiene límite; una vez que se
ha establecido la conexión, el par de sockets funciona como los
streams: todos los datos se leen inmediatamente, en el mismo
orden en que se van recibiendo.
UDP es un protocolo desordenado, no garantiza que los
datagramas que se hayan enviado sean recibidos en el mismo
orden por el socket de recepción. Al contrario, TCP es un
protocolo ordenado, garantiza que todos los paquetes que se
envíen serán recibidos en el socket destino en el mismo orden
en que se han enviado.
En resumen, TCP parece más indicado para la
implementación de servicios de red como un control
remoto (rlogin, telnet) y transmisión de ficheros (ftp);
que necesitan transmitir datos de longitud
indefinida.
UDP es menos complejo y tiene una menor
sobrecarga sobre la conexión; esto hace que sea el
indicado en la implementación de aplicaciones
cliente/servidor en sistemas distribuidos montados
sobre redes de área local.