¿Qué tipo de proyecto podemos hacer en la programación de sockets Java?

Se pueden realizar muchos proyectos divertidos utilizando la API de programación de Socket proporcionada por Java .

He escrito una aplicación de chat grupal usando la clase MulticastSocket (Java Platform SE 7). Un MulticastSocket es un DatagramSocket (UDP), con capacidades adicionales para unirse a ” grupos ” de otros hosts de multidifusión en Internet.

Aquí está el código: (menos de 100 líneas en un solo archivo)

import java.net. *;
import java.io. *;
import java.util. *;

clase pública GroupChat
{
Private static final String TERMINATE = “Salir”;
nombre de cadena estática;
estático volátil booleano terminado = falso;

public static void main (String [] args)
{
if (args.length! = 2)
System.out.println (“Se requieren dos argumentos: “);
más
{
tratar
{
InetAddress group = InetAddress.getByName (args [0]);
int port = Integer.parseInt (args [1]);

Scanner sc = nuevo escáner (System.in);
System.out.print (“Ingrese su nombre:”);
nombre = sc.nextLine ();

MulticastSocket socket = nuevo MulticastSocket (puerto);
socket.setTimeToLive (0); // Dado que estamos implementando esto solo en localhost (para una subred configúrelo como 1)
socket.joinGroup (grupo);

Thread t = new Thread (nuevo ReadThread (socket, grupo, puerto));
t.start (); // Genera un hilo para leer los mensajes enviados al grupo actual

System.out.println (“Comience a escribir mensajes … \ n”);
mientras (cierto)
{
Mensaje de cadena;
mensaje = sc.nextLine ();
if (message.equalsIgnoreCase (GroupChat.TERMINATE))
{
terminado = verdadero;
socket.leaveGroup (grupo);
socket.close ();
descanso;
}
mensaje = nombre + “:” + mensaje;
byte [] buffer = mensaje.getBytes ();
DatagramPacket datagram = new DatagramPacket (buffer, buffer.length, group, port);
socket.send (datagrama);
}
}
catch (SocketException se)
{
System.out.println (“Error al crear el socket”);
se.printStackTrace ();
}
catch (IOException es decir)
{
System.out.println (“Error al leer / escribir desde / al socket”);
es decir, printStackTrace ();
}
}
}
}
La clase ReadThread implementa Runnable
{
zócalo privado MulticastSocket;
grupo privado de InetAddress;
puerto int privado;
privado estático final int MAX_LEN = 1000;

ReadThread (socket MulticastSocket, grupo InetAddress, puerto int)
{
this.socket = socket;
this.group = grupo;
this.port = puerto;
}

@Anular
vacío público run ()
{
while (! GroupChat.finished)
{
byte [] buffer = nuevo byte [ReadThread.MAX_LEN];
DatagramPacket datagram = new DatagramPacket (buffer, buffer.length, group, port);
Mensaje de cadena;
tratar
{
socket.receive (datagrama);
mensaje = nueva cadena (búfer, 0, datagram.getLength (), “UTF-8”);
if (! message.startsWith (GroupChat.name))
System.out.println (mensaje);
}
catch (IOException e)
{
System.out.println (“¡Enchufe cerrado!”);
}
}
}
}

Guarde el archivo como GroupChat.java y compílelo usando javac y luego ejecute el programa usando 2 argumentos de línea de comando como se especifica. Un host de multidifusión se especifica mediante una dirección IP de clase D y un número de puerto UDP estándar. Las direcciones IP de clase D están en el rango 224.0.0.0 a 239.255.255.255 , inclusive. La dirección 224.0.0.0 está reservada y no debe utilizarse.

Aquí hay una salida de muestra del programa anterior:

He utilizado la dirección IP del host de multidifusión como 239.0.0.0 y el número de puerto como 1234 (ya que los números de puerto 0 a 1023 están reservados).

Hay 3 miembros en el grupo: Ironman , CaptainAmerica y Groot . Inicie los 3 terminales primero antes de enviar el mensaje, de lo contrario, los mensajes que se envían antes de iniciar el terminal se pierden (ya que no hay una función de búfer incorporado para almacenar los mensajes). Necesitamos dos hilos en esta aplicación. Uno para aceptar la entrada del usuario (usando la clase java.util.Scanner ) y el otro para leer los mensajes enviados desde otros clientes. Por lo tanto, he separado el hilo que hace el trabajo de lectura en la clase ReadThread . Para abandonar el grupo, cualquiera de los usuarios puede escribir Salir para finalizar la sesión.

El programa anterior se ejecuta en una sola máquina. La programación de sockets está destinada a la programación distribuida. El mismo fragmento de código cuando está presente en diferentes máquinas que tienen Java instalado puede satisfacer ese requisito.

Esto es solo la lógica del servicio básico. El proyecto sería aún más fascinante si se desarrolla el front-end. Puede usar AWT (Abstract Window Toolkit) de Java o su contraparte avanzada, Java Swing para desarrollar el front-end. Como esto no formaría parte de la programación de Socket, lo dejaré intacto sin entrar en detalles.

Puntos adicionales:

Puede incorporar la función de seguridad de red al realizar el cifrado antes de enviar el mensaje a través de la red. Las técnicas primitivas como el cifrado César o los métodos avanzados como RSA se pueden utilizar para realizar el cifrado-descifrado. Puede intentar usar RMI (Invocación de método remoto) de Java para realizar la misma tarea. Aquí, puede aprovechar la abstracción ofrecida por Java al máximo. Sin embargo, si su objetivo principal es la eficiencia, la programación de Socket es la mejor opción. Como no requiere ningún soporte de tiempo de ejecución, es un poco más rápido en comparación con RMI.

Gracias por el A2A Sunil Hiray

Puede escribir un chat cliente / servidor de usuario múltiple / único. Lo hice como mi proyecto de semestre universitario. Le informaría sobre cómo puede lograr eso.

Para un cliente-servidor de chat multiusuario, tendría que escribir dos componentes:

1. Servidor
2. Cliente

Servidor

En el servidor, abriría un ServerSocket que sondearía las solicitudes entrantes de diferentes clientes en un bucle infinito y cada vez que se conecte un nuevo cliente, cree un nuevo hilo para escuchar a ese cliente en particular.

Servidor de clase {

inicio público vacío () {
int portNo = 8000;
ServerSocket ss = nuevo ServerSocket (portNo);
while (verdadero) {
Socket s = ss.accept (); // esto bloquea hasta que un nuevo cliente se conecta
ServerThread st = new ServerThread (this, s);
Hilo t = nuevo Hilo (st);
t.start ();
}
}

public static void main (String args) {
Servidor s = nuevo Servidor ();
s.start ();
}
}

La clase ServerThread implementa Runnable {

servidor servidor privado;
toma de corriente privada;

Public ServerThread (servidor del servidor, socket de socket) {
this.server = servidor;
this.socket = socket;
// establece InputStream y OutputStream
}

public void run () {

}
}

Ahora cada instancia de ServerThread tiene un socket que se comunica con un usuario de chat. Además, cada uno de estos sockets tendrá un InputStream y un OutputStream para leer y escribir desde y hacia el cliente. El cliente tendría un socket similar y flujos similares de modo que el flujo de salida del cliente se conecte al flujo de entrada del servidor y viceversa.

Ahora digamos que Alice y Bob quieren usar el sistema de chat. Su servidor tendría dos instancias de ServerThread, llamémoslas STA y STB , Sockets correspondientes, SA y SB y transmisiones como ISA, ISB, OSA y OSB .

Ahora, Alice quiere enviar un mensaje a Bob (¡Oh, Dios mío! No creo estar escribiendo estas palabras hoy, que he leído innumerables veces en los libros de redes).

El ISA dentro de SA (dentro de STA) puede leer el mensaje enviado por Alice. Esto es muy facil. Pero el problema es que el servidor tiene que enviar este mensaje a Bob, que requiere acceso a OSB dentro de SB (dentro de STB). Para tener acceso al OSB dentro de STA, la clase del servidor central debe intervenir. Es por eso que se pasa a cada instancia de servidor de ServerThread para que se produzca la comunicación.

Agreguemos un Mapa a la clase de servidor que almacena todos los usuarios ServerThread en la clase de Servidor.

Vea los cambios de código a continuación en negrita:

[código]

Servidor de clase {
Mapa privado srvThrds =
nuevo HashMap <>;

inicio público vacío () {
int portNo = 8000;
ServerSocket ss = nuevo ServerSocket (portNo);
while (verdadero) {
Socket s = ss.accept (); // esto bloquea hasta que un nuevo cliente se conecta
ServerThread st = new ServerThread (this, s);
Hilo t = nuevo Hilo (st);
t.start ();
}
}

public Map getUserThreads () {
return srvThrds;
}

public static void main (String args) {
Servidor s = nuevo Servidor ();
s.start ();
}
}

La clase ServerThread implementa Runnable {

servidor servidor privado;
toma de corriente privada;

Public ServerThread (servidor del servidor, socket de socket) {
this.server = servidor;
this.socket = socket;
// establece InputStream y OutputStream
Cadena uName = // solicitar nombre de usuario
server.getUserThreads (). put (uName, esto);
}

public void run () {

}
}

[/código]

Ahora, STA (Alice’s ServerThread) debe buscar OSB (Bob’s OutputStream) de la instancia del servidor y escribir en él. Hecho. Bob recibe el mensaje. Entonces ahora necesita completar el método de ejecución de la clase ServerThread:

[código]
La clase ServerThread implementa Runnable {


public void run () {
while (verdadero) {
// Esto es solo un código de demostración, no real
Mensaje de cadena = socket.getInputStream (). ReadNextMessage ();
// El mensaje incluye el nombre de usuario y el texto del destinatario separados por:
Cadena destinatario = getRecipient (mensaje); // método privado
Texto de cadena = getText (mensaje); // método privado
OutputStream os = server.getUserThreads ()
.get (destinatario) .getSocket ()
.getOutputStream ();

os.write (mensaje);
}
}
}
[/código]

Eh !! Hecho con el servidor (Por supuesto, sería defectuoso y sin los mejores amigos).

Cliente

En el cliente, debe ejecutar dos subprocesos, uno que sigue sondeando la entrada del usuario y lo envía, lo escribe en el servidor y el otro que sigue sondeando los mensajes entrantes y los imprime al usuario. Escribamos una clase de cliente de inicio.

clase Cliente {
toma de corriente privada;
cadena estática privada SERVER_ADDRESS = “localhost”;
int estático privado PORT = 8000;
Cliente público (Socket s) {
this.socket = s;
// establece InputStream y OutputStream
}
inicio público vacío () {
Socket s = nuevo Socket (SERVER_ADDRESS, PORT);
Cliente c = nuevo Cliente (s);
Escritor w = nuevo escritor (este);
Hilo tw = nuevo Hilo (w);
Lector r = nuevo Lector (este);
Hilo tr = nuevo Hilo (r);
tw.start ();
tr.start ();
}
}

class Writer implementa Runnable {

Cliente cliente privado;

Escritor público (cliente cliente) {
this.client = cliente;
}

public void run () {
while (verdadero) {
Cadena m = // leer mensaje del usuario
client.getSocket (). getOutputStream (). write (m);
}
}
}

class Reader implementa Runnable {

Cliente cliente privado;
Consola de consola privada;

Lector público (Cliente cliente) {
this.client = cliente;
this.console = Console.getConsole ();
}

public void run () {
while (verdadero) {
Cadena m = client.getSocket (). GetInputStream (). Read ();
console.write (m);
}
}
}

Feliz chat !!!!