Commit 29d4a024 authored by Administrator's avatar Administrator

Initial commit

Initial commit with the already existing examples code and some code
clean up.
parents
#Eclipse
.settings
.project
.classpath
#Maven
target
#General
bak
This diff is collapsed.
# Ejemplos de Multihilo
Ejemplos de multihilo incluidos en el Tema 3 de la asignatura DAI.
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>es.uvigo.esei.dai</groupId>
<artifactId>multithreading</artifactId>
<version>1.0.0</version>
<name>Ejemplos de DAI - Multithilo</name>
<inceptionYear>2014</inceptionYear>
<url>https://sing-group.org/dt/gitlab/dai-2223/multihilo</url>
<developers>
<developer>
<name>Miguel Reboiro-Jato</name>
<organization>Escola Superior de Enxeñaría Informática -
Universidade de Vigo</organization>
<organizationUrl>https://esei.uvigo.es/</organizationUrl>
<email>mrjato@uvigo.gal</email>
</developer>
</developers>
<licenses>
<license>
<name>GNU GENERAL PUBLIC LICENSE, Version 3</name>
<url>http://www.gnu.org/licenses/gpl.html</url>
<distribution>repo</distribution>
</license>
</licenses>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<!-- Plugin versions -->
<license-maven-plugin.version>2.2.0</license-maven-plugin.version>
<maven-compiler-plugin.version>3.11.0</maven-compiler-plugin.version>
<!-- license-maven-plugin configuration -->
<license.licenseName>gpl_v3</license.licenseName>
<license.copyrightOwners>Miguel Reboiro Jato</license.copyrightOwners>
<license.organizationName>Universidade de Vigo</license.organizationName>
<license.addJavaLicenseAfterPackage>false</license.addJavaLicenseAfterPackage>
</properties>
<contributors>
<contributor>
<name>Miguel Reboiro Jato</name>
<email>mrjato@uvigo.gal</email>
<organization>Escola Superior de Enxeñaría Informática -
Universidade de Vigo</organization>
<organizationUrl>https://esei.uvigo.es/</organizationUrl>
<roles>
<role>author</role>
<role>professor</role>
</roles>
</contributor>
</contributors>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>license-maven-plugin</artifactId>
<version>${license-maven-plugin.version}</version>
<executions>
<execution>
<id>first</id>
<goals>
<goal>update-file-header</goal>
</goals>
<phase>process-sources</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
/*-
* #%L
* Ejemplos de DAI - Multithilo
* %%
* Copyright (C) 2014 - 2023 Miguel Reboiro Jato
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-3.0.html>.
* #L%
*/
package es.uvigo.esei.dai.threads;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
public class DataSocketIOManager implements IOManager {
private final Socket socket;
private final DataInputStream dis;
private final DataOutputStream dos;
public DataSocketIOManager(Socket socket) throws IOException {
this.socket = socket;
this.dis = new DataInputStream(socket.getInputStream());
this.dos = new DataOutputStream(socket.getOutputStream());
}
public Socket getSocket() {
return this.socket;
}
@Override
public boolean canRead() throws IOException {
return !this.socket.isClosed() && this.socket.getInputStream().available() > 0;
}
@Override
public void println(String line) throws IOException {
this.dos.writeUTF(line);
this.dos.flush();
}
@Override
public String readLine() throws IOException {
return this.dis.readUTF();
}
}
/*-
* #%L
* Ejemplos de DAI - Multithilo
* %%
* Copyright (C) 2014 - 2023 Miguel Reboiro Jato
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-3.0.html>.
* #L%
*/
package es.uvigo.esei.dai.threads;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
public class EchoClient {
public static void main(String[] args) {
// Búfer de entrada por teclado
final BufferedReader console = new BufferedReader(new InputStreamReader(System.in));
try (Socket socket = new Socket(InetAddress.getLocalHost(), 50000)) {
// Conexión con el servidor
final SocketIOManager ioManager = new SocketIOManager(socket);
// Bucle principal:
// 1. Lectura de teclado
// 2. Envío al servidor
// 3. Comprobación de finalización
// 4. Recepción y salida por consola de la respuesta
String line;
while ((line = console.readLine()) != null) { // 1
System.out.println("INPUT: " + line);
ioManager.println(line); // 2
if (line.equalsIgnoreCase("quit")) {
break; // 4
}
System.out.println("ECHO: " + ioManager.readLine()); // 3
}
} catch (final UnknownHostException e) {
System.out.println("Unknown host: localhost");
} catch (final IOException e) {
System.out.println("Connection error: " + e.getMessage());
}
}
}
/*-
* #%L
* Ejemplos de DAI - Multithilo
* %%
* Copyright (C) 2014 - 2023 Miguel Reboiro Jato
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-3.0.html>.
* #L%
*/
package es.uvigo.esei.dai.threads;
import java.io.IOException;
public interface IOManager {
public void println(String line) throws IOException;
public String readLine() throws IOException;
public boolean canRead() throws IOException;
}
/*-
* #%L
* Ejemplos de DAI - Multithilo
* %%
* Copyright (C) 2014 - 2023 Miguel Reboiro Jato
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-3.0.html>.
* #L%
*/
package es.uvigo.esei.dai.threads;
import java.io.IOException;
import java.net.Socket;
public class ServiceThread implements Runnable {
private final Socket socket;
public ServiceThread(Socket clientSocket) throws IOException {
this.socket = clientSocket;
}
@Override
public void run() {
try (this.socket) {
final SocketIOManager ioManager = new SocketIOManager(this.socket);
String message;
while (!(message = ioManager.readLine()).equalsIgnoreCase("quit")) {
ioManager.println(message.toUpperCase());
}
} catch (final IOException e) {
e.printStackTrace();
}
}
}
/*-
* #%L
* Ejemplos de DAI - Multithilo
* %%
* Copyright (C) 2014 - 2023 Miguel Reboiro Jato
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-3.0.html>.
* #L%
*/
package es.uvigo.esei.dai.threads;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class SocketIOManager implements IOManager {
private final Socket socket;
private final BufferedReader reader;
private final PrintWriter writer;
public SocketIOManager(Socket socket) throws IOException {
this.socket = socket;
this.reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
this.writer = new PrintWriter(socket.getOutputStream());
}
public Socket getSocket() {
return this.socket;
}
@Override
public boolean canRead() throws IOException {
return !this.socket.isClosed() && this.socket.getInputStream().available() > 0;
}
@Override
public void println(String line) throws IOException {
this.writer.println(line);
this.writer.flush();
}
@Override
public String readLine() throws IOException {
return this.reader.readLine();
}
}
/*-
* #%L
* Ejemplos de DAI - Multithilo
* %%
* Copyright (C) 2014 - 2023 Miguel Reboiro Jato
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-3.0.html>.
* #L%
*/
package es.uvigo.esei.dai.threads.example0;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import es.uvigo.esei.dai.threads.SocketIOManager;
public class EchoServer {
public static void main(String[] args) {
try (ServerSocket serverSocket = new ServerSocket(50000)) {
// Bucle principal:
// 1. Aceptación de la conexión
// 2. Recepción de mensajes
// 3. Respuesta a los mensajes
while (true) {
// 1. Aceptación de la conexión
try (Socket clientSocket = serverSocket.accept()) {
try {
final SocketIOManager manager = new SocketIOManager(clientSocket);
String message;
// 2. Recepción de mensajes
while (!(message = manager.readLine()).equalsIgnoreCase("quit")) {
manager.println(message.toUpperCase()); // 3. Respuesta
}
} catch (final IOException ioe) {
System.err.println("Connection error: " + ioe.getMessage());
}
}
}
} catch (final IOException e) {
System.err.println("Server socket could not be created: " + e.getMessage());
}
}
}
/*-
* #%L
* Ejemplos de DAI - Multithilo
* %%
* Copyright (C) 2014 - 2023 Miguel Reboiro Jato
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-3.0.html>.
* #L%
*/
package es.uvigo.esei.dai.threads.example1;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import es.uvigo.esei.dai.threads.SocketIOManager;
public class EchoServerNoThreads {
public static void main(String[] args) {
try (ServerSocket serverSocket = new ServerSocket(50000)) {
// Socket servidor. El método accept estará bloqueado un máximo de
// 100 ms.
serverSocket.setSoTimeout(100);
// Almacenamiento de los gestores de E/S con los clientes
final List<SocketIOManager> ioManagers = new ArrayList<>();
// Bucle principal:
// 1. Comprobar si hay una nueva conexión
// 2. Dar servicio a los cliente
// 1. Leer entrada
// 2a. Si recibimos "quit" cerramos la conexión
// 2b. En otro caso, reenviamos lo recibido en mayúsculas
while (true) {
// 1. Comprobación de si hay conexiones nuevas
try {
final Socket clientSocket = serverSocket.accept();
ioManagers.add(new SocketIOManager(clientSocket));
} catch (final SocketTimeoutException ste) {
}
// 2. Atención a los clientes que están en espera
final Iterator<SocketIOManager> itIOManagers = ioManagers.iterator();
while (itIOManagers.hasNext()) {
final SocketIOManager ioManager = itIOManagers.next();
// Para evitar el bloqueo se comprueba si hay algo que leer
while (ioManager.canRead()) {
// 1. Leer entrada
final String message = ioManager.readLine();
if (message.equalsIgnoreCase("quit")) {
// 2a. Cerrar conexión
ioManager.getSocket().close();
itIOManagers.remove();
} else {
// 2b. Responder
ioManager.println(message.toUpperCase());
}
}
}
}
} catch (final IOException e) {
System.err.println("Server socket could not be created");
}
}
}
/*-
* #%L
* Ejemplos de DAI - Multithilo
* %%
* Copyright (C) 2014 - 2023 Miguel Reboiro Jato
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-3.0.html>.
* #L%
*/
package es.uvigo.esei.dai.threads.example2;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import es.uvigo.esei.dai.threads.ServiceThread;
public class ThreadEchoServer {
public static void main(String[] args) {
try (ServerSocket serverSocket = new ServerSocket(50000)) {
while (true) {
final Socket clientSocket = serverSocket.accept();
new Thread(new ServiceThread(clientSocket)).start();
}
} catch (final IOException e) {
System.err.println("Server socket could not be created");
}
}
}
/*-
* #%L
* Ejemplos de DAI - Multithilo
* %%
* Copyright (C) 2014 - 2023 Miguel Reboiro Jato
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-3.0.html>.
* #L%
*/
package es.uvigo.esei.dai.threads.example3;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import es.uvigo.esei.dai.threads.ServiceThread;
public class ThreadPoolEchoServer {
public static void main(String[] args) {
try (ServerSocket serverSocket = new ServerSocket(50000)) {
final ExecutorService threadPool = Executors.newFixedThreadPool(50);
while (true) {
final Socket clientSocket = serverSocket.accept();
threadPool.execute(new ServiceThread(clientSocket));
}
} catch (final IOException e) {
System.err.println("Server socket could not be created");
}
}
}
/*-
* #%L
* Ejemplos de DAI - Multithilo
* %%
* Copyright (C) 2014 - 2023 Miguel Reboiro Jato
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-3.0.html>.
* #L%
*/
package es.uvigo.esei.dai.threads.example4;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousChannelGroup;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class AsynchronousMultiThreadedEchoServer {
public static void main(String[] args) throws IOException {
// Permite utilizar un thread pool para manejar las peticiones
final ExecutorService threadPool = Executors.newFixedThreadPool(50);
final AsynchronousChannelGroup group = AsynchronousChannelGroup.withThreadPool(threadPool);
// Creación del "server socket" asíncrono
final AsynchronousServerSocketChannel ssListener = AsynchronousServerSocketChannel.open(group)
.bind(new InetSocketAddress(50000));
// Registro de un callback para manejar las peticiones
ssListener.accept(null, new CompletionHandler<AsynchronousSocketChannel, Void>() {
@Override
public void completed(final AsynchronousSocketChannel result, Void attachment) {
// El callback se vuelve a registrar para manejar las peticiones
// posteriores
ssListener.accept(null, this);
// La lectura de peticiones se hace también de modo asíncrono
final ByteBuffer buffer = ByteBuffer.allocate(4096);
result.read(buffer, null, new CompletionHandler<Integer, Void>() {
@Override
public void completed(Integer length, Void attachment) {
if (length > 0) {
final String message = new String(buffer.array(), 0, length).toUpperCase();
result.write(ByteBuffer.wrap(message.getBytes()));
// El callback se vuelve a registrar
buffer.clear();
result.read(buffer, null, this);
}
}
@Override
public void failed(Throwable exc, Void attachment) {
exc.printStackTrace();
}
});
}
@Override
public void failed(Throwable exc, Void attachment) {
exc.printStackTrace();
}
});
try {
// Bloqueo del hilo actual en espera de que finalice el servicio
group.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
} catch (final InterruptedException e) {
e.printStackTrace();
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment