Echando código: Escribir un servidor sencillo en Java

Esta es una típica pregunta de entrevista de programación: Escriba un servidor sencillo en Java, el cual esté en capacidad de atender a varios clientes a la vez.

El truco aqui es abstraer la definición de una tarea; El servidor recibe la nueva conexión (un Socket) y es allí en donde deberíamos crear una nueva hebra de ejecución (Thread) para atender al cliente. Por supuesto, como el tiempo es corto no le van a pedir que maneje los siguientes casos:

  • Seguridad (como controlar quien se conecta)
  • Optimizaciones: Piscinas de hebras de ejecución (thread pools)
  • Registro de eventos
  • Inicialización, finalización del servidor

Pero el que no le pidan la implementación no significa que usted al menos no deberia al menos saber como hacerlo (le pueden preguntar la idea general).

El sitio de Java tiene tutoriales extremadamente completos sobre Sockets, así que esta vez yo sólo me voy a limitar a colcarles el código aqui y un enlace para que se lo baje. Yo utilicé un número mayor que 1024 en el puerto de manera que usted pueda correr este demonio sin ser root.

Veamos entonces la división de tareas; Primero definimos una tarea la cual es la que actualmente hace el trabajo:

   1:import java.io.IOException;
2:import java.io.OutputStream;
3:import java.io.InputStream;
4:import java.io.PrintWriter;
5:import java.io.BufferedReader;
6:import java.io.InputStreamReader;
7:
8:import java.net.Socket;
9:/**
10: * This class takes care of a client connecting to the server.
11: * License: GPL
12: * Blog: El Angel Negro - http://elangelnegro.blogspot.com
13: * @author Jose V Nunez Z
14: * @version 0.1 - 02/28/2005
15: */
16:public class Task implements Runnable {
17: private Socket socket;
18: private Server server;
19:
20: /**
21: * Class constructor
22: * @param socket Client Socket
23: * @since 0.1
24: */
25: public Task(Socket socket, Server server) {
26: this.socket = socket;
27: this.server = server;
28: }
29:
30:
31: /**
32: * Method called by the current executing thread
33: * @since 0.1
34: */
35: public void run() {
36: PrintWriter out = null;
37: BufferedReader in = null;
38: try {
39: out = new PrintWriter(
40: socket.getOutputStream(),
41: true
42: );
43: in = new BufferedReader(
44: new InputStreamReader(
45: socket.getInputStream()
46: )
47: );
48: String line = null;
49: while( (line = in.readLine()) != null ) {
50: /*
51: * Now take the input and write it back to the
52: * client.
53: */
54: out.write(line);
55: out.write("\n");
56: if (line.equals(".")) {
57: break;
58: }
59: }
60: line = null;
61: } catch (IOException ioexp) {
62: ioexp.printStackTrace();
63: } finally {
64: if (out != null) {
65: try {
66: out.close();
67: } catch (IOException ignore) {
68: // Empty
69: };
70: }
71: if (in != null) {
72: try {
73: in.close();
74: } catch (IOException ignore) {
75: // Empty
76: };
77: }
78: if (socket != null) {
79: try {
80: socket.close();
81: } catch (IOException ignore) {
82: // Empty
83: };
84: }
85: server.decrementClient();
86: }
87:
88: }
89:}

Y el servidor el cual escucha por nuevas conexiones y despacha nuevas tareas:

   1:import java.io.IOException;
2:import java.net.ServerSocket;
3:import java.net.Socket;
4:/**
5: * This class shows how to create a simple Echo server with TCP Sockets.
6: * License: GPL
7: * Blog: El Angel Negro - http://elangelnegro.blogspot.com
8: * @author Jose V Nunez Z
9: * @version 0.1 - 02/28/2005
10: */
11:public class Server {
12:
13: private int clients = 0;
14:
15: /**
16: * Default port to be used by the server
17: */
18: public static final int PORT = 1973;
19:
20: protected synchronized void incrementClient() {
21: clients++;
22: }
23:
24: protected synchronized void decrementClient() {
25: clients--;
26: }
27:
28: /**
29: * Command line processing
30: * @param args - ignored
31: * @throws IOException
32: * @since 0.1
33: */
34: public static void main(String [] args) throws IOException {
35: ServerSocket server = null;
36: try {
37: server = new ServerSocket(PORT);
38: System.out.println("Started echo server on port: "
39: + PORT);
40: Server instance = new Server();
41: while(true) {
42: Socket socket = server.accept();
43: instance.incrementClient();
44: System.out.println("Connected client #: "
45: + instance.clients);
46: Task task = new Task(socket, instance);
47: Thread thread = new Thread(task);
48: thread.start();
49: }
50: } catch (IOException ioexp) {
51: throw ioexp;
52: } finally {
53: try {
54: if (server != null) {
55: server.close();
56: }
57: } catch (IOException ignore) {
58: // Empty
59: }
60: }
61: }
62:}

Aquí está el enlace para que se lo baje.

2 thoughts on “Echando código: Escribir un servidor sencillo en Java

  1. Hi! ayer estaba que venía a preguntarte que le había pasadao a Veneblogs, me decía: – El único que puede ayudarnos es El Angel Negro, nuestro CyberSúperHéroe 😉

  2. Jejejeje, si Adriana, yo vi el desastre de Veneblogs ayer. Sospecho que fué un lio de base de datos, alguna cucaracha en el codigo de PHP.

    Sin embargo los chamos de Veneblogs son muy buenos, asi que no necesitan de ninguna ayuda 😀

Comments are closed.