You need to sign in or sign up before continuing.
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