在唯一服务器中执行两个对象runnable。插座

时间:2014-12-23 13:30:45

标签: java multithreading sockets runnable

我有一个问题,我认为很容易,但我不知道如何解决。

如果我的客户端使用参数-p执行,则服务器从数据库创建一个文件并将其返回给客户端。如果客户端没有参数,则它会向服务器发送可序列化对象,服务器将其保存在数据库中。

我的客户代码:

public class cliente {
    public static void main(String[] args) {

        // común
        String hostname = "localhost";
        int port = 6789;
        Socket clientSocket = null;

        // descarga fichero
        String ficheroDescargado = null;

        // Almacena datos
        BufferedReader br = null;
        ObjectOutputStream os = null;
        String str = "";
        Map<DatosAEnviar, DatosAEnviar> datos = new TreeMap<DatosAEnviar, DatosAEnviar>();

        if (args.length != 0 && args[0] == "-p") {
            System.out.println("Descarga fichero");
            try {
                // Instanciamos la conexión con el socket
                clientSocket = new Socket(hostname, port);
                System.out.println("IP " + clientSocket.getInetAddress().toString());
                ficheroDescargado = "descarga_tienda_"
                        + clientSocket.getInetAddress().toString()
                                .replace("localhost/", "") + ".txt";
                byte[] mybytearray = new byte[1024];
                InputStream is = clientSocket.getInputStream();
                FileOutputStream fos = new FileOutputStream(ficheroDescargado);
                BufferedOutputStream bos = new BufferedOutputStream(fos);
                int bytesRead = is.read(mybytearray, 0, mybytearray.length);
                bos.write(mybytearray, 0, bytesRead);
                bos.close();
                // Cerramos el socket
                clientSocket.close();
            } catch (UnknownHostException e) {
                System.err.println("Don't know about host: " + hostname);
            } catch (IOException e) {
                System.err.println("Por favor, inicialice primero el servidor "
                        + hostname);
            }
        } else {
            System.out.println("Leer fichero");
            datos = leerFichero();
            System.out.println("Pintamos lo recibido");
            for (Entry<DatosAEnviar, DatosAEnviar> itrDatos : datos.entrySet()) {
                DatosAEnviar clave = itrDatos.getKey();
                DatosAEnviar valor = itrDatos.getValue();
                System.out.println(clave + "  ->  " + valor.toString());
            }
            try {
                // Instanciamos la conexión con el socket
                clientSocket = new Socket(hostname, port);
                // Abrimos el canal entrada de datos. Nos la enviará el servidor
                // para confirmar que ha procesado OK
                br = new BufferedReader(new InputStreamReader(
                        clientSocket.getInputStream()));
                // Abrimos el canal de salida para mandar al servidor la
                // colección
                // MapTree
                os = new ObjectOutputStream(clientSocket.getOutputStream());
                // Enviamos por el canal de salida hacia el servidor los daros
                // en el
                // MapTree
                os.writeObject(datos);
                // Esperamos la respuesta del servidor.
                while ((str = (String) br.readLine()) != null) {
                    System.out.println(str);
                    if (str.equals("bye"))
                        break;
                }
                // Cerramos el canal de salida
                os.close();
                // Cerramos el canal de entrada
                br.close();
                // Cerramos el socket
                clientSocket.close();
            } catch (UnknownHostException e) {
                System.err.println("Don't know about host: " + hostname);
            } catch (IOException e) {
                System.err.println("Por favor, inicialice primero el servidor"
                        + hostname);
            }
        }
    }

客户端还可以,工作正常。问题出在服务器上:

我的服务器代码:

public class Server2 {
    public static void main(String args[]) {
        int port = 6789;
        Server2 server = new Server2(port);
        server.startServer();
    }

    // Definimos el socket del servidor y el socket del cliente
    ServerSocket echoServer = null;
    Socket clientSocket = null;
    // Definimos la variable para almacenar el nº de conexiones
    int numConnections = 0;
    int port;

    public Server2(int port) {
        this.port = port;
    }

    public void stopServer() {
        System.out.println("Server cleaning up.");
        System.exit(0);
    }

    public void startServer() {
        // Abrimos el socket del servidor. No se pueden definir puertos por
        // debajo de 1024

        try {
            echoServer = new ServerSocket(port);
        } catch (IOException e) {
            System.out.println(e);
        }

        System.out.println("Servidor listo y esperando conexiones de clientes...");

        while (true) {
            try {
                clientSocket = echoServer.accept();
                numConnections++;
                 **// Insert in BD
                 Server2Connection oneconnection = new Server2Connection(clientSocket, numConnections, this);
                 // Generate file and send to client
                 //Server1Connection oneconnection = new Server1Connection(clientSocket, numConnections, this);

                new Thread(oneconnection).start();**

            } catch (IOException e) {
                System.out.println(e);
            }
        }
    }
}

class Server2Connection implements Runnable {
    PrintStream os;
    Socket clientSocket;
    int id;
    Server2 server;
    ObjectOutputStream oos = null;
    ObjectInputStream ois = null;
    Map<DatosAEnviar, DatosAEnviar> datos;

    public Server2Connection(Socket clientSocket, int id, Server2 server) {
        this.clientSocket = clientSocket;
        this.id = id;
        this.server = server;
        System.out.println("Conexión " + id + " establecida en: " + clientSocket);
        System.out.println("Conexión " + id + " establecida por: "
                + clientSocket.getInetAddress());
        try {
            os = new PrintStream(clientSocket.getOutputStream());
            ois = new ObjectInputStream(clientSocket.getInputStream());
        } catch (IOException e) {
            System.out.println(e);
        }
    }

    public void run() {
        Connection con;
        Statement smt;
        boolean serverStop = false;

        try {
            Class.forName("com.mysql.jdbc.Driver");
            con = DriverManager.getConnection("jdbc:mysql://localhost:3306/hotel",
                    "root", "root");

            // Hacemos el cast del stream recibido al tipo de objeto esperado,
            // en este caso un objeto del tipo MapTree
            while ((datos = (Map<DatosAEnviar, DatosAEnviar>) ois.readObject()) != null) {
                for (Entry<DatosAEnviar, DatosAEnviar> itrDatos : datos.entrySet()) {
                    DatosAEnviar clave = itrDatos.getKey();
                    DatosAEnviar valor = itrDatos.getValue();
                    System.out.println(clave + "  ->  " + valor.toString());
                    // Insertamos en la tabla de BBDD cada registro del MapTree
                    // recibido
                    String query = "insert into registro (id_conex, vendedor, ventas, ip_tienda) values( '"
                            + id
                            + "','"
                            + valor.getNombre()
                            + "','"
                            + valor.getVentas()
                            + "','"
                            + clientSocket.getInetAddress().toString().replace("/", "") + "');";
                    smt = con.createStatement();
                    smt.executeUpdate(query);
                }
                // Enviamos al cliente confirmación de que hemos procesado la
                // información correctamente
                os.println("bye");
                break;
            }

            System.out.println("Conexión " + id + " cerrada.");

            // Cerramos la conexión de BBDD
            con.close();
            // Cerramos el canal de entrada
            ois.close();
            // Cerramos el canal de salida
            os.close();
            // Cerramos el socket con el cliente
            clientSocket.close();

            if (serverStop)
                server.stopServer();
        } catch (IOException e) {
            System.out.println(e);
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

class Server1Connection implements Runnable {
    Socket clientSocket;
    int id;
    Server2 server;
    File myFile = null;
    OutputStream os = null;
    BufferedInputStream bis = null;
    FileInputStream fis = null;

    public Server1Connection(Socket clientSocket, int id, Server2 server) {
        this.clientSocket = clientSocket;
        this.id = id;
        this.server = server;
        System.out.println("Conexión " + id + " establecida en: " + clientSocket);
        try {
            os = clientSocket.getOutputStream();    
        } catch (IOException e) {
            System.out.println(e);
        }
    }

    public void run() {

        boolean serverStop = false;
        Connection con;
        Statement smt;
        ResultSet rs;
        try {

            // Conexión a la BBDD
            Class.forName("com.mysql.jdbc.Driver");
            con = DriverManager.getConnection("jdbc:mysql://localhost:3306/hotel","root", "root");
            //Generamos el fichero
            FileWriter writer = new FileWriter("registro_tieda_"+clientSocket.getInetAddress().toString().replace("/", "") + ".txt");
            smt=con.createStatement();
            String query ="SELECT * FROM registro WHERE ip_tienda='" + clientSocket.getInetAddress().toString().replace("/", "") + "';";
            rs = smt.executeQuery(query);
            while(rs.next()) {
                writer.append(rs.getString(3));
                writer.append(';');
                writer.append(rs.getString(4));
                writer.append(';');
                writer.append(rs.getString(5));
                writer.append('\n');                
            }
            writer.close();

            // Enviamos el fichero
              File myFile = new File("registro_tieda_"+clientSocket.getInetAddress().toString().replace("/", "") + ".txt");
              fis = new FileInputStream(myFile);
              bis = new BufferedInputStream(fis);
              byte[] mybytearray = new byte[(int) myFile.length()];
              bis.read(mybytearray, 0, mybytearray.length);
              os.write(mybytearray, 0, mybytearray.length);
              os.flush();
              bis.close();


            // Enviamos al cliente confirmación de que hemos procesado la
            // información correctamente

            System.out.println("Conexión " + id + " cerrada.");

            // Cerramos la conexión de BBDD
            con.close();
            clientSocket.close();
            // Cerramos el fichero


            if (serverStop)
                server.stopServer();
        } catch (IOException e) {
            System.out.println(e);
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
    }
}

我的代码中有两个方法,运行一个方法取决于我是想插入数据库还是生成文件。现在我必须手动注释掉粗线。

如何从客户端向服务器发送要执行的选项?如果客户端参数是-p,我想在客户端程序中执行Server1Connection方法,而不使用args Server2Connection方法。

1 个答案:

答案 0 :(得分:0)

问题是您不向服务器发送任何内容以让它知道要使用哪种方法。您需要建立协议,以便客户端可以向服务器请求正确的操作。

您的代码中也应该只有一个run方法,具体取决于客户端要求的方法,执行正确的操作。