Autor Tema: Error java.net.BindException: Address already in use: Cannot bind sockets UDP  (Leído 2881 veces)

jordy96

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 5
    • Ver Perfil
¡Hola comunidad programadora! Soy nuevo en este sitio, mi nombre es Jordy, mucho gusto.

Estoy aquí para aprender más acerca del lenguaje java. Tengo un problema con un ejercicio y ya le he dado mil vueltas y no logro realizarlo. Este ejercicio me pide que tengo que conectarme a un servidor en donde el cliente hace una petición y solo el servidor responderá con números octales (0,1,2,3,4,5,6,7), pero la conexión debe de ser solo comunicación UDP ¿Cómo puedo realizar eso en el siguiente código? Necesito ayuda  :'(

Código: [Seleccionar]
//código del servidor 

/*COMUNICACION UDP (protocolo sin conexión/IP) CLIENTE-SERVIDOR CON HILOS
La conexión UDP no es orientada a conexión, es decir, el servidor en principio
no sabe de donde viene el mensaje, aunque lo puede saber mirando el datagrama que le llega.
En otras palabras y comparando con la conexión TCP, UDP no necesita saber quien se conecta a él.
En UDP se envían datagramas a modo de mensajes.*/


package sockets4_servidor;

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

public class Sockets4_servidor {

static formu1 formu = new formu1();
static Sockets4_servidor meto = new Sockets4_servidor();
int PUERTO = 5000; //Puerto servidor   
String mensa1;
byte[] buffer = new byte[1024]; //buffer donde se almacenara los mensajes
DatagramSocket socketUDP;
DatagramPacket respuesta;
InetAddress direccion;
int puertoCliente;

public static void main(String[] args) {
formu.setVisible(true);meto.conexion();meto.ejecutarconexion();}


public void ejecutarconexion() {
Thread hilo = new Thread(new Runnable() {
@Override
@SuppressWarnings("empty-statement")
 public void run() {
 while (true) {   
  try {mensaje();}
  finally {;} } } } );
 hilo.start();}

public void conexion() {
try {   
formu1.jTextArea1.append("Esperando conexión entrante en el puerto: " + PUERTO+ "\n");
direccion = InetAddress.getLocalHost();
formu1.jTextArea1.append("Servidor IP: " + direccion + "\n");}       
catch (IOException e) {System.err.println("Error "+e);} } 

public void mensaje() {
try {
 //Creacion del socket
 socketUDP = new DatagramSocket(PUERTO);
 //Preparo la respuesta
 DatagramPacket peticion = new DatagramPacket(buffer, buffer.length);
//Recibo el datagrama
 socketUDP.receive(peticion);
 //Convierto lo recibido y mostrar el mensaje
 mensa1 =new String(peticion.getData());
 formu1.jTextArea1.append(mensa1+"\n");
 //Obtengo el puerto y la direccion de origen
 //Sino se quiere responder, no es necesario
 puertoCliente = peticion.getPort();
 direccion = peticion.getAddress();
 mensa1="SERVIDOR: Hola Cliente";
 buffer = mensa1.getBytes();
 //creo el datagrama
 respuesta = new DatagramPacket(buffer, buffer.length, direccion, puertoCliente);
 //Envio la información
 socketUDP.send(respuesta); }       
catch (IOException e) {System.err.println("Error "+e);} } 
 
}
« Última modificación: 18 de Abril 2021, 20:56 por Ogramar »

Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 985
    • Ver Perfil
Re: practica y ejercicio Sockets
« Respuesta #1 en: 08 de Marzo 2021, 12:13 »
En este tipo de tareas no puedo ayudar, desconozco el tema de sockets y conexiones.  :(

A ver si pasa alguien que sí pueda aportar algo.
Suerte y un saludo.
NO respondo dudas por mensaje privado
Publicando vuestras dudas en el foro público conseguimos:
- Que más gente aporte respuestas mejores o complementarias.
- Que otras personas puedan aprender de vuestras dudas.

Mejor en PÚBLICO que en privado. Gracias

Mario R. Rancel

  • Administrador
  • Experto
  • ********
  • APR2.COM
  • Mensajes: 1978
    • Ver Perfil
Re: practica y ejercicio Sockets
« Respuesta #2 en: 08 de Marzo 2021, 20:41 »
Hola jordy96, en el código que has pasado falta código para que compile. No está el código de la clase formu1, que parece representar a un formulario. También falta el código de la clase Sockets4_servidor.

¿No tienes el resto del código?

Este ejercicio parece referirse a una máquina que actúa como servidor que recibe peticiones de clientes. Por tanto vas a necesitar un código para la máquina que actúe como servidor y otro código para la máquina que actúe como cliente. Ambas máquinas tienen que estar "arrancadas" (en ejecución) para que pueda materializarse el intercambio de datagramas.

Por otro lado, indicas que el servidor tiene que responder con números octales (0,1,2,3,4,5,6,7) pero, ¿responde aleatoriamente a cualquier petición, o tiene que responder determinado número según cuál sea el contenido de la petición? ¿Cuál es exactamente el enunciado o rúbrica del ejercicio?

Este es un ejemplo de implementación para una máquina cliente que envía datagramas UDP:

Código: [Seleccionar]
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;

public class Cliente_usa_udp
{
public static void main(String args[]) throws IOException
{
Scanner sc = new Scanner(System.in);

// Paso 1: crear el socket
DatagramSocket ds = new DatagramSocket();

InetAddress ip = InetAddress.getLocalHost();
byte buf[] = null;

// iterar mientras el usuario no introduzca "adios"
while (true) {
String inp = sc.nextLine();

// convertir la entrada en un array de bytes.
buf = inp.getBytes();

// Paso 2: crear el datagramPacket para enviar los datos
DatagramPacket DpSend = new DatagramPacket(buf, buf.length, ip, 1234);

// Paso 3: invocar send para enviar los datos
ds.send(DpSend);

// El bucle termina si el usuario introduce <<adios>>
if (inp.equals("adios"))
break;
}
}
}

Y este para una máquina servidor que recibe datagramas y muestra lo que recibe, en este caso no emite respuesta y se cierra si recibe <<adios>> del cliente:

Código: [Seleccionar]
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;

public class Servidor_usa_udp
{
public static void main(String[] args) throws IOException {
// Paso 1: crear un puerto para escuchar, en este ejemplo el puerto es el 1234
DatagramSocket ds = new DatagramSocket(1234);
byte[] receive = new byte[65535];

DatagramPacket DpReceive = null;
while (true) {

// Paso 2: crear un DatgramPacket para recibir los datos
DpReceive = new DatagramPacket(receive, receive.length);

// Paso 3: recibir los datos en un buffer de bytes
ds.receive(DpReceive);

System.out.println("Cliente:-" + data(receive));

// Cerrar el servidor si el cliente envía "adios"
if (data(receive).toString().equals("adios")) {
System.out.println("El cliente envió adios.....SALIENDO");
break;
}

// Limpiar el buffer después de cada mensaje.
receive = new byte[65535];
}
}

// Método auxiliar para convertir el array de bytes en un string
public static StringBuilder data(byte[] a) {
if (a == null)
return null;
StringBuilder ret = new StringBuilder();
int i = 0;
while (a[i] != 0)
{
ret.append((char) a[i]);
i++;
}
return ret;
}
}


jordy96

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 5
    • Ver Perfil
Re: practica y ejercicio Sockets
« Respuesta #3 en: 09 de Marzo 2021, 01:32 »
Sí, tengo el resto de código tanto del clientes su form y del servidor también. Solo pasé le código de servidorsocket:

Voy a pasar todo el código que tengo---

codigo de sockest-servidor  y su formu1

Código: [Seleccionar]
/*COMUNICACION UDP (protocolo sin conexión/IP) CLIENTE-SERVIDOR CON HILOS
La conexión UDP no es orientada a conexión, es decir, el servidor en principio
no sabe de donde viene el mensaje, aunque lo puede saber mirando el datagrama que le llega.
En otras palabras y comparando con la conexión TCP, UDP no necesita saber quien se conecta a él.
En UDP se envían datagramas a modo de mensajes.*/


package sockets4_servidor;

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

public class Sockets4_servidor {

static formu1 formu = new formu1();
static Sockets4_servidor meto = new Sockets4_servidor();
int PUERTO = 5000; //Puerto servidor   
String mensa1;
byte[] buffer = new byte[1024]; //buffer donde se almacenara los mensajes
DatagramSocket socketUDP;
DatagramPacket respuesta;
InetAddress direccion;
int puertoCliente;

public static void main(String[] args) {
formu.setVisible(true);meto.conexion();meto.ejecutarconexion();}


public void ejecutarconexion() {
Thread hilo = new Thread(new Runnable() {
@Override
@SuppressWarnings("empty-statement")
 public void run() {
 while (true) {   
  try {mensaje();}
  finally {;} } } } );
 hilo.start();}

public void conexion() {
try {   
formu1.jTextArea1.append("Esperando conexión entrante en el puerto: " + PUERTO+ "\n");
direccion = InetAddress.getLocalHost();
formu1.jTextArea1.append("Servidor IP: " + direccion + "\n");}       
catch (IOException e) {System.err.println("Error "+e);} } 

public void mensaje() {
try {
 //Creacion del socket
 socketUDP = new DatagramSocket(PUERTO);
 //Preparo la respuesta
 DatagramPacket peticion = new DatagramPacket(buffer, buffer.length);
//Recibo el datagrama
 socketUDP.receive(peticion);
 //Convierto lo recibido y mostrar el mensaje
 mensa1 =new String(peticion.getData());
 formu1.jTextArea1.append(mensa1+"\n");
 //Obtengo el puerto y la direccion de origen
 //Sino se quiere responder, no es necesario
 puertoCliente = peticion.getPort();
 direccion = peticion.getAddress();
 mensa1="";
 buffer = mensa1.getBytes();
 //creo el datagrama
 respuesta = new DatagramPacket(buffer, buffer.length, direccion, puertoCliente);
 //Envio la información
 socketUDP.send(respuesta); }       
catch (IOException e) {System.err.println("Error "+e);} } 
 
}



// código de formu-servidor

Código: [Seleccionar]
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package sockets4_servidor;

import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Usuario
 */
public class formu1 extends javax.swing.JFrame {

    Sockets4_servidor socke4 = new Sockets4_servidor();
    /**
     * Creates new form formu1
     */
    public formu1() {
        initComponents();
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                         
    private void initComponents() {

        jScrollPane1 = new javax.swing.JScrollPane();
        jTextArea1 = new javax.swing.JTextArea();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("SERVIDOR");

        jTextArea1.setColumns(20);
        jTextArea1.setRows(5);
        jScrollPane1.setViewportView(jTextArea1);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap(47, Short.MAX_VALUE)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 594, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(37, 37, 37))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(28, 28, 28)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 125, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(38, Short.MAX_VALUE))
        );

        pack();
        setLocationRelativeTo(null);
    }// </editor-fold>                       

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(formu1.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(formu1.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(formu1.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(formu1.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new formu1().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify                     
    private javax.swing.JScrollPane jScrollPane1;
    public static javax.swing.JTextArea jTextArea1;
    // End of variables declaration                   
}



//codigo sockest-cliente

Código: [Seleccionar]
/*COMUNICACION UDP (protocolo sin conexión/IP) CLIENTE-SERVIDOR CON HILOS

La conexión UDP no es orientada a conexión, es decir, el servidor en principio
no sabe de donde viene el mensaje, aunque lo puede saber mirando el datagrama que le llega.
En otras palabras y comparando con la conexión TCP, UDP no necesita saber quien se conecta a él.
En UDP se envían datagramas a modo de mensajes.*/

package sockets4_cliente;

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


public class Sockets4_cliente {

static formu1 formu = new formu1();
static Sockets4_cliente meto = new Sockets4_cliente();
String HOST = "localhost"; //Host servidor (IP o localhost)
int PUERTO = 5000; //Puerto servidor   
String mensa1;
byte[] buffer = new byte[1024];   //buffer donde se almacenara los mensajes
InetAddress direccionServidor;


public static void main(String[] args) throws UnknownHostException {
formu.setVisible(true);meto.conexion();meto.ejecutarconexion();}

public void ejecutarconexion() {
Thread hilo = new Thread(new Runnable() {
@Override
@SuppressWarnings("empty-statement")
 public void run() {
 while (true) {       
  try {mensaje();}
  finally {;} } } } );
   hilo.start();}
     

public void conexion() throws UnknownHostException {
 String nombrepc= InetAddress.getLocalHost().getHostName();
 formu1.jTextArea1.append("Nombre PC= "+nombrepc +" conectado a "+HOST+"\n");
 //Obtengo la localizacion de localhost
 direccionServidor = InetAddress.getByName(HOST);
}
               
public void mensaje() {
try {
    //Creo el socket de UDP
    DatagramSocket socketUDP = new DatagramSocket();
    //Convierto el mensaje a bytes
    mensa1="Hola Cliente";
    buffer = mensa1.getBytes();
    //Creo un datagrama
    DatagramPacket pregunta = new DatagramPacket(buffer, buffer.length, direccionServidor, PUERTO);
    //Lo envio con send
    socketUDP.send(pregunta);
    //Preparo la respuesta
    DatagramPacket peticion = new DatagramPacket(buffer, buffer.length);
    //Recibo la respuesta
     socketUDP.receive(peticion);
     //Cojo los datos y lo muestro
     mensa1 = new String(peticion.getData());
     formu1.jTextArea1.append(mensa1+"\n"); }
 catch (IOException e) {System.err.println("Error "+e);} } 

}


//codigo de formu1-cliente

Código: [Seleccionar]
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package sockets4_cliente;

/**
 *
 * @author Usuario
 */
public class formu1 extends javax.swing.JFrame {

    Sockets4_cliente socke4 = new Sockets4_cliente();
    /**
     * Creates new form formu1
     */
    public formu1() {
        initComponents();
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                         
    private void initComponents() {

        jScrollPane1 = new javax.swing.JScrollPane();
        jTextArea1 = new javax.swing.JTextArea();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("CLIENTE");

        jTextArea1.setColumns(20);
        jTextArea1.setRows(5);
        jScrollPane1.setViewportView(jTextArea1);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(58, 58, 58)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 499, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(62, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(25, 25, 25)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 119, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(50, Short.MAX_VALUE))
        );

        pack();
        setLocationRelativeTo(null);
    }// </editor-fold>                       

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(formu1.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(formu1.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(formu1.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(formu1.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new formu1().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify                     
    private javax.swing.JScrollPane jScrollPane1;
    public static javax.swing.JTextArea jTextArea1;
    // End of variables declaration                   
}

Eso es todo lo que tengo
« Última modificación: 18 de Abril 2021, 21:00 por Ogramar »

jordy96

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 5
    • Ver Perfil
Re: practica y ejercicio Sockets
« Respuesta #4 en: 09 de Marzo 2021, 01:46 »
Por otro lado, indicas que el servidor tiene que responder con números octales (0,1,2,3,4,5,6,7) pero, ¿responde aleatoriamente a cualquier petición, o tiene que responder determinado número según cuál sea el contenido de la petición? ¿Cuál es exactamente el enunciado o rúbrica del ejercicio?
y respondiendo a esto mi enunciado solo es esto--que el servidor solo contesta con numero octal nada mas dice

jordy96

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 5
    • Ver Perfil
Re: practica y ejercicio Sockets
« Respuesta #5 en: 09 de Marzo 2021, 01:51 »
Tema:  Sockets en Java

Objetivos:  Realizar el desarrollo de prototipos sockets en Java gráfico

Instrucciones:

1.   La tarea es individual y se plantea emplear un proyecto básico de Sockets-Java con el objetivo de mejorarlo, desarrollando determinadas clases.
2.   Desarrolle el proyecto en códigos java para su posterior envío en formato ZIP.

Sockets4_cliente
Sockets4_servidor   
El servidor solo contesta mensajes con números octal
(0,1,2,3,4,5,6,7)

eso es todo lo que dice mi rubrica y el código ya lo publique es todo eso y se tiene que modificar con las condiciones que me pide que solo conteste con numero octal --el cliente hace una consulta al servidor o ingresa un numero del 0 al 7 si se pasa de ese rango por decir un 8 el servidor debe de contestar con un error eso es lo que me dijo el docente..

Ogramar

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 2659
    • Ver Perfil
He ejecutado el código proporcionado pero salta el siguiente error sobre el cliente:

Error java.net.BindException: Address already in use: Cannot bind

Fíjate que sobre la máquina cliente tenemos este código:

while (true) {       
  try {mensaje();}
  finally {;} }

Y el método mensaje() lo que hace es en cada ocasión invocar:

DatagramSocket socketUDP = new DatagramSocket();

DatagramSocket() Constructs a datagram socket and binds it to any available port on the local host machine.

Para el servidor en cambio se invoca:

socketUDP = new DatagramSocket(PUERTO); habiendo establecido previamente int PUERTO = 5000; //Puerto servidor

La numeración de puertos en una máquina para los protocolos TCP y UDP es finita, normalmente en los rangos 0-1023, 1024-49151 y 49152-65535

Un bucle que ocupa puertos continuamente debe terminar en un colapso, por eso interpreto yo que aparece el <<Error java.net.BindException: Address already in use: Cannot bind>>

 

Sobre la educación, sólo puedo decir que es el tema más importante en el que nosotros, como pueblo, debemos involucrarnos.

Abraham Lincoln (1808-1865) Presidente estadounidense.

aprenderaprogramar.com: Desde 2006 comprometidos con la didáctica y divulgación de la programación

Preguntas y respuestas

¿Cómo establecer o cambiar la imagen asociada (avatar) de usuario?
  1. Inicia sesión con tu nombre de usuario y contraseña.
  2. Pulsa en perfil --> perfil del foro
  3. Elige la imagen personalizada que quieras usar. Puedes escogerla de una galería de imágenes o subirla desde tu ordenador.
  4. En la parte final de la página pulsa el botón "cambiar perfil".