English 中文(简体)
Java顶服务器 最后一个客户连接起来是唯一能够读到袖珍的客户。
原标题:Socket server in Java, The last client connected is the only can read the socket
  • 时间:2011-08-29 16:08:19
  •  标签:
  • java
  • sockets

I have a problem with a socket server that I m developing.

首先,袖珍服务器随后采用以下类别:

  • 页: 1 (不包括服务器)

  • 页: 1 (基本等待新连接,然后作为分处理)

  • (从家中收到一只袖珍物品,并写上并读在册)

  • Class Panel_mensajes (Shows info about the socket connections in a jpanel)

  • 客户是一纸空文节目。

问题在于两个或两个以上的客户有关系,只有最后一个联系客户能够读到书状。 我已经用碎块 s块进行逐步检查,但我可以发现错误。

Here is my code:

Main_Servidor 班次:

public class Main_Servidor {



    public static void main(String[] args) {

        Panel_mensajes PanelMensajes = new Panel_mensajes();
        PanelMensajes.setVisible(true);

        EjecutarServidor ejectuarservidor = new EjecutarServidor();

        ejectuarservidor.ejecutar();

    }

}

EjecutarServidor 班次:

public class EjecutarServidor {

    private static final int puerto = 1025;
    private static final int conexionesMaximas = 3;

    private ExecutorService iniciarThread;
    private static ServerSocket listener;
    private static Socket socket;
    private static boolean EsperarConexiones = true;

    public EjecutarServidor()
    {
        //Crea la pila de sub-procesos y se la asigna al objeto iniciarThread 
        iniciarThread = Executors.newFixedThreadPool(conexionesMaximas);
    }

    public void ejecutar()
    {

        Panel_mensajes.MostrarMensaje("ESPERANDO CONEXIONES...

"); 

        try{

            listener = new ServerSocket(puerto); //Esta a la escucha de nuevas conexiones
                                                 //en el puerto especificado.

            GregorianCalendar fecha = new GregorianCalendar(); //Genera la fecha incluyendo la hora

            while(EsperarConexiones){ //Mientras EsperarConexiones sea TRUE esperará por
                                      //nuevas conexiones.
                socket = null;
                socket = listener.accept(); //Acepta la nueva conexión y la asigna a un objeto socket

                //Muesta en pantalla los datos de la nueva conexión
                Panel_mensajes.MostrarMensaje("NUEVA CONEXION " + 
                        socket.getInetAddress().toString().replace("/", "") + ":" 
                        + socket.getPort() + ", "
                        + fecha.getTime() + "
" + "
"
                    );

                //Se crea un nuevo objeto ManejoConexion al cual se le pasa como parametro
                //el objeto socket llamado  socket  que contiene la nueva conexión
                ManejoConexion con_nva = new ManejoConexion(socket);

                //Ejecuta el nuevo objeto ManejoConexion como un nuevo sub-proceso.
                iniciarThread.execute(con_nva);

            }

        } catch (IOException ioe) {
            Panel_mensajes.MostrarMensaje("IOException en socket!: * " + ioe);
        }
    }

    //Deja de escuchar nuevas peticiones
    public static void cerrarServidor()
    {
        try
        {
            EsperarConexiones = false;
            listener.close();
            socket.close();

        }catch(SocketException SoE)
        {
            Panel_mensajes.MostrarMensaje("SocketException por cerrar servidor, todo OK");
            //SoE.printStackTrace();

        }catch(IOException ioe)
        {
            Panel_mensajes.MostrarMensaje("IOException por cerrar servidor, todo OK");
            //ioe.printStackTrace();
        }finally
        {
            System.exit(0);
        }

    }


}

<>ManejoConexion> 班次:

import java.io.DataInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;

public class ManejoConexion implements Runnable {

    private Socket server;
    private String line;
    private DataInputStream in;
    private static PrintWriter out;
    private static Protocolo proto;
    private static Boolean ACTIVO = true;


    ManejoConexion(Socket server) throws IOException {

        //Recibe un objecto Socket e inicializa la variable server
        this.server = server;

    }

    //Hace que se ejecute un objeto de esta clase como un sub-proceso
    public void run () {

        try {

            //Recibe las tramas de datos desde el servidor
            in = new DataInputStream (server.getInputStream());

            //Envia tramas de datos al servidor
            out = new PrintWriter(server.getOutputStream());

            this.responderPeticiones("+OK");

            //Mantiene abierto el flujo de datos desde el servidor mientras no se cumplan las
            //condiciones.
            Panel_mensajes.MostrarMensaje(Thread.currentThread() + "
");

            while((line = in.readLine()) != null && !line.equals("TERM")) {

                //Panel_mensajes.MostrarMensaje("CLIENTE " + server.getInetAddress().toString().replace("/", "") + " DICE -> " + line + "
");
                //proto.entrada(line);

                this.responderPeticiones(line);

                if(!ACTIVO) break;

            }

            this.responderPeticiones("
" + "CONEXION TERMINADA: " + server.getInetAddress().toString().replace("/", ""));

            Panel_mensajes.MostrarMensaje("
" + "CONEXION TERMINADA: " + server.getInetAddress().toString().replace("/", "") + "
" + "
");
            server.close();

        } catch (IOException ioe) {
            Panel_mensajes.MostrarMensaje("
IOException AL RECIBIR PETICION: " + ioe.getMessage());
            //ioe.printStackTrace();
        }

    }

    //Se encarga de responder peticiones a los clientes
    public void responderPeticiones(String s) throws IOException
    {
        String input = s;
        String direccion = server.getInetAddress().toString().replace("/", "");

        out.write("SERVIDOR DICE A " + direccion + " -> " + input + "
");
        out.flush();

    }

    public static void TerminarConexion()
    {
        ACTIVO = false;
        proto = null;

    }

}

(一) 添加<条码> 男女公民姓名 班级,因为并不重要

最佳回答

了解你的法典并不容易(我猜测这部法律是空洞的或高射的)。 问题似乎在<条码>中,即:

private static ServerSocket listener;
private static Socket socket;
private static Boolean EsperarConexiones

如果一个新客户把客户连接起来,你只是通过下列方式重新提及客户以前的袖珍:

socket = null;
socket = listener.accept();

This may not work when several clients connect concurrently as the reference to socket may break between

socket = listener.accept();

and

ManejoConexion con_nva = new ManejoConexion(socket);

Defining listener as a static attribute is definitely not a good practive, but should work given your samples. But defining the static socket is definitely an error and may lead to unexpected results. You should move the Socket declaration into EjecutarServidor.ejecutar() like:

       while(EsperarConexiones){ 

            Socket socket = listener.accept(); //<-- fix HERE

            Panel_mensajes.MostrarMensaje("NUEVA CONEXION " + 
                    socket.getInetAddress().toString().replace("/", "") + ":" 
                    + socket.getPort() + ", "
                    + fecha.getTime() + "
" + "
"
                );

            ManejoConexion con_nva = new ManejoConexion(socket);
            iniciarThread.execute(con_nva);
        }

总结这一点,看看它是否改变了你的行为。

问题回答

在您的<代码>ManejoConexion类别中,你有3个固定变量,这些变量应为t。 尤其是将列入LAST案的Socket输出流的“PrintWriter,因此,首先将突然开始讨论最后一种情况。

实际上,I m并不确定什么是<条码>proto和ACTIVO,但<条码>下的静态变量肯定不是静止的。

注意<条码> 私人静态印刷体; 载于ManejoConexion,不应是静态的。





相关问题
Spring Properties File

Hi have this j2ee web application developed using spring framework. I have a problem with rendering mnessages in nihongo characters from the properties file. I tried converting the file to ascii using ...

Logging a global ID in multiple components

I have a system which contains multiple applications connected together using JMS and Spring Integration. Messages get sent along a chain of applications. [App A] -> [App B] -> [App C] We set a ...

Java Library Size

If I m given two Java Libraries in Jar format, 1 having no bells and whistles, and the other having lots of them that will mostly go unused.... my question is: How will the larger, mostly unused ...

How to get the Array Class for a given Class in Java?

I have a Class variable that holds a certain type and I need to get a variable that holds the corresponding array class. The best I could come up with is this: Class arrayOfFooClass = java.lang....

SQLite , Derby vs file system

I m working on a Java desktop application that reads and writes from/to different files. I think a better solution would be to replace the file system by a SQLite database. How hard is it to migrate ...

热门标签