En este nuevo post mostraremos como hacer un chat mediante el uso de Sockets en Java en el ambiente de programacion Netbeans. Los Sockets sirven para comunicar procesos de diferentes maquinas de una red.
Haremos un servidor y un cliente utilizando Sockets.
Del lado del Servidor se tiene un bucle infinito que espera conexiones de clientes. Cuando un cliente se conecta el servidor acepta la conexion y genera dos threads: uno para enviar datos y el otro para recibirlos.
Del lado del Cliente se tiene que esperar un Servidor para poder conectarse, cuando se conecta al servidor se generan dos threads, al igual que en el Servidor uno para enviar y otro para recibir los datos.
Los threads que se generan del lado del servidor y del cliente son los mismos.
La clase principal del Servidor es identica a la clase principal del cliente; la unica diferencia esta en el main, el servidor espera conexiones del cliente y el cliente busca servidor para conectarse.
Para nuestro ejemplo utilizaremos localhost para poder correr el programa en nuestra propia maquina.
Es importante tener en cuenta que puerto se va a utilizar para poder abrirlo con anterioridad, en nuestro caso abriremos el puerto 11111.
Se debe conocer que las asignaciones a los puertos comprendidos entre los valores (0 - 1023) estan determinados por la IANA (Internet Assigned Numbers Authority). y no se los puede utilizar de otro manera.
Se puede utilizar los puertos comprendidos entre los valores (1024 - 65535).
Se debe conocer que las asignaciones a los puertos comprendidos entre los valores (0 - 1023) estan determinados por la IANA (Internet Assigned Numbers Authority). y no se los puede utilizar de otro manera.
Se puede utilizar los puertos comprendidos entre los valores (1024 - 65535).
Nuestro programa cuenta con dos paquetes, uno para el servidor y otro para el cliente; los mismo que contiene threads identicos para envio y recepcion de datos.
Empezaremos describiendo las clases del lado del servidor:
Clase PrincipalChat:
Esta clase implementa la interfaz grafica para poder mostrar los mensajes entrantes y un JTextField para poder enviarlos. La interfaz contiene un menu para poder salir del programa.
En el main se puede ver que se espera conexiones de clientes.
En el main se puede ver que se espera conexiones de clientes.
Clase ThreadEnvia:
En esta clase establecemos nuestro canal de salida tipo ObjectOutputStream, el cual nos sirve para escribir el mensaje, enviarlo y mostrarlo en pantalla mediante el metodo enviarDatos().
Ademas declaramos la variable conexion tipo Socket, la cual se encarga de establecer el flujo de datos entre cliente y servidor.
En esta clase establecemos nuestro canal de salida tipo ObjectOutputStream, el cual nos sirve para escribir el mensaje, enviarlo y mostrarlo en pantalla mediante el metodo enviarDatos().
Ademas declaramos la variable conexion tipo Socket, la cual se encarga de establecer el flujo de datos entre cliente y servidor.
Clase ThreadRecibe:
En esta clase establecemos nuestro canal de entrada tipo ObjectInputStream, el cual se encarga de recibir los mensajes enviados por el cliente o servidor.
Aqui se procesa los mensajes recibidos y luego son mostrados en pantalla.
Es importante aclarar que se debe cerrar el canal de entrada de datos y el Socket de conexion una vez finalizado el flujo de datos.
En esta clase establecemos nuestro canal de entrada tipo ObjectInputStream, el cual se encarga de recibir los mensajes enviados por el cliente o servidor.
Aqui se procesa los mensajes recibidos y luego son mostrados en pantalla.
Es importante aclarar que se debe cerrar el canal de entrada de datos y el Socket de conexion una vez finalizado el flujo de datos.
En el paquete Cliente encontramos:
Clase PrincipalChat:
Esta clase implementa la interfaz grafica para poder mostrar los mensajes entrantes y un JTextField para poder enviarlos. La interfaz contiene un menu para poder salir del programa.
Esta clase busca servidores para poder conectarse.
Clase PrincipalChat:
Esta clase implementa la interfaz grafica para poder mostrar los mensajes entrantes y un JTextField para poder enviarlos. La interfaz contiene un menu para poder salir del programa.
Esta clase busca servidores para poder conectarse.
Las clases descritas en el paquete Cliente: ThreadRecibe y ThreadEnvia son exactamente las mismas que se describieron en el paquete Servidor.
Nuestro proyecto se vera asi:
El resultado final se mostrara de la siguiente manera:
Para descargar el proyecto completo click en la siguiente imagen:
Skydrive
Dropbox
La case PrincipalChat para el cliente cual es?
ResponderBorrarHola que tal! la segunda "Clase PrincipalChat" es la destinada para el cliente.
Borrary para agregarle emotics no tienes o no tienes codigo de eso???
BorrarEl proyecto no se deja descargar amigo
ResponderBorrarDebes tener abierto el hotmail para poder descargar el proyecto!
BorrarExclente aporte!
ResponderBorrarSi necesitara que el cliente se encontrara en un pc independiente al servidor, que modificaciones debería hacer? agradecería mucho tu ayuda.
ResponderBorrarLas modificaciones deben hacerse tanto del lado del servidor como de cliente. Se debe cambiar la ip y abrir puertos de entrada y salida en ambos casos.
BorrarServidor: Clase PrincipalChat
linea 27: cambiar la ip 127.0.0.1 por la ip de la pc a la que se desea conectar.
linea 85: cambiar el puerto 11111 por el puerto que abrio en servidor.
Cliente: Clase PrincipalChat
linea 28: cambiar la ip 127.0.0.1 por la ip de la pc a la que se desea conectar.
linea 87: cambiar el puerto 11111 por el puerto que se abrio en el cliente.
Los puertos abiertos en el servidor y en el cliente deben ser los mismos.
Para saber como abrir puertos seguir el siguiente link:
http://ofeewds.blogspot.com/2012/09/como-abrir-puertos-de-entrada-y-salida.html
el código está muy bien, ¿pero como se podría hacer que se pida un Nick al entrar?, luego si son dos clientes no hay problema al hablar cliente-servidor pero si se conectan varios clientes ¿como un cliente direcciona el mensaje a otro? o como un cliente manda un mensaje al resto como broadcast, los mensajes desde el servidor si llegan al resto de clientes pero los de los cliente solo llegan al servidor y no entre ellos.
BorrarGracias de antemano.
Hola que tal!
BorrarPara tu primera pregunta: aqui un chat que pide un nick al entrar.
https://skydrive.live.com/#cid=CB2C976AE9CB5D07&id=CB2C976AE9CB5D07%21280
Se ha creado un metodo ingresarNick(), el cual pide un nick al entrar al programa y es llamado desde el main.
Respecto a tu segunda pregunta: pido disculpas, no he realizado un programa asi!
Ok gracias, veré lo de ingresar el Nick, lo del envío a todos los clientes es ver como manejar los hilos de envío y recibo de mensajes metiendo un Id por cliente, si averiguo como hacerlo, meto el código.
BorrarHola quiero conectar en otra pc...es necesario cambiar los puertos 11111.... no entendi como abrir los puertos...el enlace que pones no esta disponible
BorrarEste comentario ha sido eliminado por el autor.
ResponderBorraroie men dice ke el archivo a sido eliminado o a expirado no lo puedes subir otravez por fa hermano espero i me pudas ayudar gracias
ResponderBorraroye bro con todo y mi cuenta de hotmail abierta y con todo y mi skydrive abierto me dice que no puedo acceder al archivo que es posible que haya sido movido o eliminado
ResponderBorrarEs muy extrano que te aparezca eso! comprobé y el enlace funciona.
BorrarCon todo acabo de actualizar el link de descarga.
Además agregué otro enlace por si el primero no te funciona!
Saludos!
como lo integro a mi una pagina web '? se podra
ResponderBorrarAqui una guia que te podria sevir!
Borrarwww.solotuweb.com/fs~id~10451.html
Hola Rafa Gallardo, Tendras el codigo por ahi, para un nuevo thread para realizar videollamada tambien ?
ResponderBorrarHola Yull! Lamentablemente no tengo un código así.
BorrarHola, estoy intentando ejecutar el programa con 2 pc conectados a la misma red, ya cambie lo de la ip y lo de los puertos, y sigue sin funcionar, que otro cambio puedo hacer para que funcione?
ResponderBorrarTienes que bajar los firewalls en ambas computadoras!
BorrarTampoco me funciono, me aparece lo siguiente:
BorrarSEVERE: null
java.net.ConnectException: Connection refused: connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:69)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:339)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:200)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:182)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:157)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:391)
at java.net.Socket.connect(Socket.java:579)
at java.net.Socket.connect(Socket.java:528)
at java.net.Socket.(Socket.java:425)
at java.net.Socket.(Socket.java:241)
at cliente.PrincipalChat.main(PrincipalChat.java:87)
Hola Rafa Gallardo, tengo el mismo problema que Rafael, cuando ejecuto el programa en el mismo computador funciona bien, pero cuando lo hago con dos computadores diferente nada; hice el cambio de la ip y cree los puertos...
BorrarHola Rafa Gallardo, tengo el mismo problema que Rafael, cuando ejecuto el programa en el mismo computador funciona bien, pero cuando lo hago con dos computadores diferente nada; hice el cambio de la ip y cree los puertos...
ResponderBorrarHola! A los mejor el antivirus no les permite conectarse! desactivenlo al igual q los firewalls!
ResponderBorrarTienen que que iniciar primero el servidor y después el cliente!
Asegúrense de haber cambiado correctamente los puertos e IPs en los lugares que se pide. El programa se ha probado y funciona correctamente.
ResponderBorrarmen disculpa pero lo corro en jcpro y me da error no se a encontrado la clase principal servidor
ResponderBorrarmen me da dos errores ayi axulio como hago
ResponderBorrarexecutor.execute(new ThreadRecibe(conexion, main)); //client
executor.execute(new ThreadEnvia(conexion, main));
Si estas ejecutando el servidor antes de ejecutar el cliente?
BorrarMen no entiendo como correrlo mira lo q me dice cuando corro el cliente
ResponderBorrar--------------------Configuration: --------------------
C:\Users\SuperMan\Desktop\ChatSockets\src\cliente\PrincipalChat.java:94: error: cannot find symbol
executor.execute(new ThreadRecibe(cliente, main));
^
symbol: class ThreadRecibe
location: class PrincipalChat
C:\Users\SuperMan\Desktop\ChatSockets\src\cliente\PrincipalChat.java:95: error: cannot find symbol
executor.execute(new ThreadEnvia(cliente, main));
^
symbol: class ThreadEnvia
location: class PrincipalChat
2 errors
Process completed.
cambiaste algo en el codigo?
Borrarno ya listo men pero necesito que envié archivos entiendes
ResponderBorraren estos días voy a subir algo parecido!
Borrarcuando men necesito uno =(
BorrarHola Rafa, a mi tampoco me funciona cuando intento conectar dos PC conectados al mismo router mediante wifi. Tengo los puertos de ambas computadoras abiertas así como los del router. Introduzco en la clase PrincipalChat del cliente la ip interna del servidor, alguna idea?
ResponderBorrarMuchas gracias y muy buen post!
baja los firewall! y desactiva el antivirus
Borrarpor favor serias tan amable de publicar nuevamente el ejemplo que permite agregar un nick?
ResponderBorrarmuchas gracias :D
seguro! aqui el link! https://www.dropbox.com/s/fwx6urp7rn6x9ol/ChatSocketsElegirNick.rar
BorrarNecesito de su ayuda..Pero necesito hacer un chat pero cuando cualquiera de los dos escriba salir o terminar
ResponderBorrarSe acabe la conexion..URGENTE
Hola no me muestra la imagen que tu colocaste es decir la de conectado al servidor y no puedo chatear(escribir) nada me podrias ayudar si tengo que modificar algo mas dentro de tu archivo...
ResponderBorrarque tal!! si vas a correr en la misma compu no tienes que modificar absolutamente nada.
BorrarPero si vas a correr en dos computadoras distintas debes de abrir los puertos (entrada y salida) y modificar las IPs. Ademas bajar los firewalls y desactivar el antivirus.
hola una pregunta como le puedo ahcer para conectarlo con dos computadoras es que no le entiendo mucho
ResponderBorrartienes que abrir puertos de entrada y salida en ambas pcs! Luego debes de cambiar la IP (127.0.0.1) por la IP de la Pc a la que te deseas conectar.
ResponderBorrarAdemas tienes que desactivar el antivirus y bajar los firewalls para poder conectarte.
Hola Rafa, tengo una duda, como modificarias la clase ChatPrincipal del paquete cliente de tal manera que se puedan crear varios clientes y todos puedan conectarse o desconectarse del servido?
ResponderBorrarhola q tal! si recuerdo bien, este programa permite ejecutar varios clientes q se conectan al sevidor.
BorrarPrimero ejecutas el servidor y luego ejecutas el cliente cuantas veces desees!!
Me sale este error cuando corro el cliente
ResponderBorrarava.net.BindException: Address already in use: JVM_Bind
at java.net.PlainSocketImpl.socketBind(Native Method)
at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:383)
at java.net.ServerSocket.bind(ServerSocket.java:328)
at java.net.ServerSocket.(ServerSocket.java:194)
at java.net.ServerSocket.(ServerSocket.java:150)
at servidor.PrincipalChat.main(PrincipalChat.java:86)
Desconecte firewall y antivirus, como lo puedo solucionar?
hey man muy bue tuto yo tambien soy programador deberias agregarme en facbeook y hablamos un rato (Y)
ResponderBorrarhttps://www.facebook.com/david.st.rock
Muy bueno está de 10 el ejemplo, saludos.
ResponderBorraramigo puedo llamar ese metodo desde un boton en una interfaz para un proyecto que estoy realizando? osea apretar el boton y que aparezca el chat.
ResponderBorrarclaro! solo debes crearte otra ventana para que puedas llamar al chat
Borrarme sale error en el servidor en la siguiente
ResponderBorrarexecutor.execute(new Recibe(conexion, main)); //client
executor.execute(new Envia(conexion, main));
tengo el mismo problema
BorrarRevisen las sugerencias que he ido poniendo a lo largo de los comentarios!!
BorrarGracias Excelente aporte, me ha servido de maravilla
ResponderBorrarMe alegro que te haya funcionado!
BorrarHola! Necesito ayuda con un programa similar. ¿Hay alguien ahí?
ResponderBorrarEn que te puedo ayudar? amiga ...
ResponderBorrarhola me gustó,me ah funcionado el chat que hiciste y me a servido para una clase en mi universidad, me gustaria como seria para que ese mismo chat se pueda o permita enviar archivo. que sea con archivos adjuntados
ResponderBorrarhola necesito ayuda con el mismo chat, aparte del chat necesito que se pueda enviar o adjuntar archivos para ese mismo ejercicio que estas publicando del chat con sockets
ResponderBorrarme alegra que te sirviera! para poder enviar archivos desde el chat debes de crear algun boton que se llame "enviar archivo" y llamar a la clase thread EnviarArchivo que te adjunto en el sig link https://www.dropbox.com/s/vtoimt7mxrzg72u/EnviarArchivo.java. Ademas debes ajuntar la clase thread RecibirArchivo https://www.dropbox.com/s/ge0vzg8ivyl57lc/RecibirArchivo.java. Ambos threads debes de ejecutarlos desde la clase PrincipalChat en la seccion "ejecucion de threads" de la siguiente manera: executor.execute(new RecibirArchivo()); y executor.execute(new EnviarArchivo(main));
Borrarok gracias, voy a ver como me va si algo te esterare preguntando de nuevo, por si algo ese te mi correo juanchopolo170@gmail.com y mi skype juanchopolo170
Borrarafa podemos hablar por skype quisiera hacer mas preguntas sobre el chat con sockets mi skype es juanchopolo170
BorrarSi te sirve aquí tienes lo que deseas.
Borrarhttp://todoenjava.blogspot.com/2013/05/chat-y-transferencia-de-archivos.html
Carolina Yumbay30 de octubre de 2013, 8:30
ResponderBorrarme sale error en el servidor en la siguiente
executor.execute(new Recibe(conexion, main)); //client
executor.execute(new Envia(conexion, main));
Me pasa lo mismo.
Pues no entiendo?? No existe ningún constructor con los nombres Recibe ni Envía, quizás debieran ser ThreadRecibe y ThreadEnvía, pero tampoco. He revisado todo el hilo y no encuentro la solución al problema.
Muy bueno, pero me he quedado a trancas.
Este comentario ha sido eliminado por el autor.
ResponderBorrarexcelente rafa!! oye para agregar un segundo cliente?
ResponderBorrarAquí un ejemplo...
Borrarhttp://todoenjava.blogspot.com/2013/05/chat-y-transferencia-de-archivos.html
que tal rafa, hay un refrán que dice que las cosas son verdaderamente tuyas hasta que las compartes...
ResponderBorrargracias por el código, servirá para el proyecto de la facultad...
:O)
OIE AMIGO Y COMO SERIA SI QUISIERA MANDAR MENSAJES DE CLIENTE A CLIENTE ???????
ResponderBorraraquí tienes un ejemplo de eso...
Borrarhttp://todoenjava.blogspot.com/2013/05/chat-y-transferencia-de-archivos.html
Aquí les comparte un chat multiusuario con transferencia de archivos; el chat en cliente servidor y la transferencia de archivos en P2P, el código se encuentra ahí mismo. También se pueden suscribir al blog.
ResponderBorrarSaludos.
http://todoenjava.blogspot.com/2013/05/chat-y-transferencia-de-archivos.html
Este comentario ha sido eliminado por el autor.
ResponderBorrarDISCULPA AL ESCRIBIR "TERMINATE" NO TERMINA LA CONEXION, PORQUE PODRA SER?
ResponderBorrarComo adjuntar archivos en este chat, algun metodo o pack destinado para lo mismo?
ResponderBorrarGracias
ResponderBorraroyes ami nadamas me parese "esperando cliente......"
ResponderBorrarHola que tal hice una aplicacion similar de cliente servidor pero solo funciona en redes locales lan quisiera saber de que manera y que puertos debo utilizar para realizar el chat por internet de casa a casa , desde ya muchas gracias :D
ResponderBorrarHola una pregunta para enviar mensajes y despues archivos como se lograria esto en el mismo socket.
ResponderBorrarhola disculpa y para poder chatear con alguien que esta en otra ciudad que yo como haria ? necesito tu ayuda porfavor
ResponderBorrarBuenas Rafa como vamos.....oye tenia una pregunta al momento de ejecutar la parte del cliente me aparecen estas tres lineas de error
ResponderBorrarException in thread "main" java.lang.UnsupportedOperationException: Not supported yet.
at cliente.ThreadRecibe.(ThreadRecibe.java:41)
at cliente.PrincipalChat.main(PrincipalChat.java:94)
podrias asesorarme en eso ? Gracias
Hola amigo tengo una pregunta..
ResponderBorrarSe puede conectar a dos computadoras que no estén en la misma red?
Excelente trabajo amigo, muchas gracias, saludos
ResponderBorrarme sale este error, me podrian ayudar por favor?
ResponderBorrarjava.net.BindException: Address already in use: JVM_Bind
at java.net.DualStackPlainSocketImpl.bind0(Native Method)
at java.net.DualStackPlainSocketImpl.socketBind(DualStackPlainSocketImpl.java:106)
at java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:387)
at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:190)
at java.net.ServerSocket.bind(ServerSocket.java:375)
at java.net.ServerSocket.(ServerSocket.java:237)
at java.net.ServerSocket.(ServerSocket.java:181)
at servidor.PrincipalChat.main(PrincipalChat.java:96)
como le puedo hacer para descargarlo no me permite porfavor
ResponderBorrarMuchas gracias por el proyecto, me ha sido de mucha ayuda. Yo le hice unos pequeños cambios para que funcionara como un chat de grupo.
ResponderBorrarJorge me gustaria tu ayuda para un proyecto que debo hacer con un chat de grupo o multihilos
BorrarQue programas necesito específicamente?
ResponderBorrarHola como llamo las clases com um boton? Es decir al presionar el boton que ejecute cliente y servidor puesto que abre ventanas pero no corre...
ResponderBorrardisculpa me podria explicar bien como implementarlo y utlizarlo , la conexion con el ip y el server , no la entiendo.
ResponderBorrarhola amigo... gracias por el aporte, sabes como hacerlo para que sea multi-usuarios
ResponderBorrarHola, disculpa , cual es la contraseña ?
ResponderBorrarIncreíble aporte amigo! Me ha servido de mucho! Gracias
ResponderBorrarGracias; sin duda este fue el unico que me ayudo. Grcias
ResponderBorrarHola. Muchas gracias por tu aporte. Salvaste mi cuatrimestre. Sos un crack.
ResponderBorrarx2
Borrargracias por la ayuda me salvaste del plan de mejoramiento
ResponderBorrarPara los que les marca error de que la dirección ya esta en uso es porque están corriendo dos veces el servidor lo que tienen que hacer es correr primero el programa de ahí dar clic derecho al proyecto y dirigirse a propiedades de ahí buscan la opción donde diga run y cambiar a clase del servidor por la del cliente lo corren obvio sin cerrar la ventana del servidor y listo ya funcionara y para volver a correrlo tienen que hacer lo mismo pero a la inversa recuerden que primero se corre el servidor y después el cliente
ResponderBorrarGracias por tu aporte esta muy completo y entendible.
ResponderBorrarUna pregunta cómo podría hacerle para enviar un mensaje desde el servidor a un cliente en específico
ResponderBorrar