gpt4 book ai didi

java - Java中的套接字服务器,最后连接的客户端是唯一可以读取套接字的

转载 作者:行者123 更新时间:2023-12-02 08:11:59 26 4
gpt4 key购买 nike

我正在开发的套接字服务器有问题。

首先,套接字服务器有以下类:

  • Main_Servidor(执行服务器)

  • EjecutarServidor(基本上等待新连接,然后将它们作为子进程运行)

  • ManejoConexion(从home接收套接字对象,并在套接字中写入和读取)

  • Panel_mensajes(显示有关jpanel中套接字连接的信息)

  • 客户端是一个用adobe air编写的小程序

问题是当两个或多个客户端连接时,只有最后一个连接的客户端可以读取套接字。我已经使用eclipse的调试器一步步检查了,但找不到错误。

这是我的代码:

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...\n\n");

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() + "\n" + "\n"
);

//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() + "\n");

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

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

this.responderPeticiones(line);

if(!ACTIVO) break;

}

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

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

} catch (IOException ioe) {
Panel_mensajes.MostrarMensaje("\nIOException 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 + "\n");
out.flush();

}

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

}

}

(我没有添加 Panel_mensajes 类,因为相关性不大)

最佳答案

在您的 ManejoConexion 类中,您有 3 个不应该的静态变量。特别是 PrintWriter,它将被设置为 LAST 实例的 Socket 输出流,因此第一个实例将突然开始与最后一个实例通信。

实际上,我不确定 protoACTIVO 的用途,但 out 静态变量绝对不应该是静态的。

关于java - Java中的套接字服务器,最后连接的客户端是唯一可以读取套接字的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7232695/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com