Bien estoy trasteando con sockets, y me tope con uno de los tutoriales de Chuidiang, que haría yo sin su wiki ;D.
Aqui esta el link:
http://www.chuidiang.com/java/sockets/hilos/socket_hilos.php
HiloDeCliente.java
// Implementa Runnable para poder ser lanzada en un hilo aparte
public class HiloDeCliente implements Runnable
{
// En el constructor recibe y guarda los parámetros que sean necesarios.
// En este caso una lista con toda la conversación y el socket que debe
// atender.
public HiloDeCliente(DefaultListModel charla, Socket socket)
{
...
}
public void run ()
{
while (true)
{
// Código para atender al cliente.
}
}
}
ServidorChat.java
public class ServidorChat
{
// Para guardar toda la conversación.
private DefaultListModel charla = new DefaultListModel();
public ServidorChat()
{
// Se crea el socket servidor
ServerSocket socketServidor = new ServerSocket(5557);
// Bucle infinito
while (true)
{
// Se espera y acepta un nuevo cliente
Socket cliente = socketServidor.accept();
// Se instancia una clase para atender al cliente y se lanza en
// un hilo aparte.
Runnable nuevoCliente = new HiloDeCliente(charla, cliente);
Thread hilo = new Thread(nuevoCliente);
hilo.start();
}
}
}
Mi pregunta esta en el Runnable de el bucle while, porque hace:
Runnable nuevoCliente = new HiloDeCliente(charla, cliente);
Thread hilo = new Thread(nuevoCliente);
No sería mas directo hacer:
HiloDeCliente nuevoCliente = new HiloDeCliente(charla, cliente);
Y extender la class HiloDeCliente de Thread?
Es decir porque implementa un Runnable y la pone "dentro" de un Thread puediendo lanzar un Thread directamente.
Si alguien puediese explicarmelo lo agradeceria mucho.
Un saludo y gracias de antemano.
CitarMi pregunta esta en el Runnable de el bucle while, porque hace:
Runnable nuevoCliente = new HiloDeCliente(charla, cliente);
Thread hilo = new Thread(nuevoCliente);
No sería mas directo hacer:
HiloDeCliente nuevoCliente = new HiloDeCliente(charla, cliente);
Y extender la class HiloDeCliente de Thread?
Es decir porque implementa un Runnable y la pone "dentro" de un Thread puediendo lanzar un Thread directamente.
Te lo pone en el comentario:
HiloDeCliente.java
// Implementa Runnable para poder ser lanzada en un hilo aparte
public class HiloDeCliente implements Runnable
{
...
}
Tiene que implementar la interfaz Runnable para poder ser lanzada en un hilo distinto. Esta manera de crear el hilo...
Runnable nuevoCliente = new HiloDeCliente(charla, cliente);
Thread hilo = new Thread(nuevoCliente);
...se debe a que la clase Thread tiene un constructor que acepta como parámetro un objeto de tipo Runnable:
Thread(Runnable target) {
...
}
Por tanto aplica polimorfismo para poder crear un hilo con ese parámetro. Aún así, el polimorfismo ya se utiliza internamente, aqui no es necesario; esto también funcionaria:
HiloDeCliente nuevoCliente = new HiloDeCliente(charla, cliente);
Thread hilo = new Thread(nuevoCliente);
Le mandamos un objeto de tipo "HiloDeCliente" pero el constructor debe recibir "Runnable", como "HiloDeCliente" implementa la interfaz "Runnable" (es un tipo padre) se aplica polimorfismo y tenemos el mismo resultado.
Saludos.
Bien, gracias por tu rápida respuesta.
Yo lo e hecho de esta manera, sin Runnable, por eso quería saber si tal y como yo lo hago esta bien.
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import javax.swing.DefaultListModel;
public class Server {
private DefaultListModel<String> allMessages = new DefaultListModel<String>();
public Server(){
try {
@SuppressWarnings("resource")
ServerSocket serverSocket = new ServerSocket(9000);
while(true){
Socket newClientSocket = serverSocket.accept();
ThreadOfClient newClientThread = new ThreadOfClient(allMessages,newClientSocket);
newClientThread.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.Socket;
import javax.swing.DefaultListModel;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
public class ThreadOfClient extends Thread implements ListDataListener{
private DefaultListModel<String> allMessages = new DefaultListModel<String>();
private DataInputStream input;
private DataOutputStream output;
public ThreadOfClient(DefaultListModel<String> allMessages, Socket socket){
this.allMessages = allMessages;
try {
input = new DataInputStream(socket.getInputStream());
output = new DataOutputStream(socket.getOutputStream());
this.allMessages.addListDataListener(this);
} catch (Exception e) {
e.printStackTrace();
}
}
public void run(){
try {
while(true){
String messageOfServer = input.readUTF();
synchronized(allMessages){
allMessages.addElement(messageOfServer);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void contentsChanged(ListDataEvent e) {
}
@Override
public void intervalAdded(ListDataEvent e) {
String text = (String) allMessages.getElementAt(e.getIndex0());
try {
output.writeUTF(text);
} catch (Exception exception) {
exception.printStackTrace();
}
}
@Override
public void intervalRemoved(ListDataEvent e) {
}
}
Un saludo y como siempre mil gracias ;)