Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
多线程文件服务器java_Java_Multithreading_File_Sockets_Objectinputstream - Fatal编程技术网

多线程文件服务器java

多线程文件服务器java,java,multithreading,file,sockets,objectinputstream,Java,Multithreading,File,Sockets,Objectinputstream,我正在用Java实现一个并发文件服务器 每个客户端都有自己与服务器的通信通道。服务器运行一个线程用于侦听所有连接请求,另一个线程用于侦听和应答每个连接。每个客户端运行一个线程,用于与de服务器通信,另一个用于侦听其他客户端所需的服务器请求文件 客户 public class Cliente { private static String nombre; private InetAddress ip; private static Socket s; private static Buff

我正在用Java实现一个并发文件服务器

每个客户端都有自己与服务器的通信通道。服务器运行一个线程用于侦听所有连接请求,另一个线程用于侦听和应答每个连接。每个客户端运行一个线程,用于与de服务器通信,另一个用于侦听其他客户端所需的服务器请求文件

客户

public class Cliente {
 private static String nombre;
 private InetAddress ip;
 private static Socket s;
 private static BufferedReader tCliente;
 private static PrintWriter fCliente;
 private static Usuario usr;
 private static String idCliente;

    public Cliente(){

    }

public static void main(String args[]){
        Cliente c=new Cliente();
        Scanner teclado=new Scanner(System.in);
        System.out.println("What´s your name?");
        nombre=teclado.nextLine();
        //construir cliente
        try {
            s= new Socket("ACER", 999);//¿Cómo obtengo la ip del Servidor?  192.168.1.101
            tCliente=new BufferedReader(new InputStreamReader(s.getInputStream()));
            fCliente=new PrintWriter(s.getOutputStream());
            MensajeConexion mConexion=
                    new MensajeConexion(InetAddress.getLocalHost().getHostName(), "ACER",nombre);
            fCliente.println(nombre);*/
            (new OyenteServidor(s,c)).start();

            while (true){
                System.out.println("Que deseas hacer?");
                System.out.println("1) Mostrar lista usuarios");
                System.out.println("2) Pedir fichero");
                System.out.println("3) Cerrar conexión");   
                int op = teclado.nextInt();
                switch (op) {
                case 1:
                break;
                case 2:
                    System.out.println("Que fichero quieres?");
                    String nombreFichero = teclado.nextLine();
                break;
                case 3:
                    s.close();
                break ;
                default:
                    System.err.println("Opción inválida");
                break;
                }
            }
        } 
        catch (IOException e) {

            e.printStackTrace();
        }


    teclado.close();
}
    public void print(String string) {
        System.out.println(string);
   }
}
服务器

public class Servidor {
private static InetAddress ipServer;
private static final int portServer=999;
private static ServerSocket listen;
private static BufferedReader fServer;
private static PrintWriter tServer;
private static Socket s;
private static Hashtable<String, Usuario> tUsuarios;
private static Hashtable<String, ObjectOutputStream> tCanales ;


public Servidor(){

}
public static void main(String args[]){
    Servidor ser=new Servidor();
    try {
        listen=new ServerSocket(portServer);
        ipServer=listen.getInetAddress();
        while(true){
            s=listen.accept();
            (new OyenteCliente(s,ser)).start();
        }
    } 
    catch (IOException e) {
        e.printStackTrace();
    }
}

public InetAddress getInetAdress(){
    return ipServer;
}

public synchronized void guardaFlujo(Usuario usr, ObjectOutputStream fOut) {
    tCanales.put(usr.getName(), fOut);

}
public synchronized void registra(Usuario usr) {
    tUsuarios.put(usr.getName(), usr);
}
}
用于侦听服务器中的每个客户端的线程在名为OyentClientListener的类中实现,而用于侦听服务器小部分的每个客户端的线程在OyentServictorServerListener中实现

客户监听器

public class OyenteCliente extends Thread {
    private Servidor servidor;
    private Socket s;   private ObjectInputStream fIn;
    private ObjectOutputStream fOut;
    private Usuario infoCliente;
    public OyenteCliente(Socket so,Servidor ser) {
       servidor=ser;
       s=so;
       try {
          fIn=new ObjectInputStream(s.getInputStream());//<---Server thread stops here
          fOut=new ObjectOutputStream(s.getOutputStream());
       } 
       catch (IOException e) {
          e.printStackTrace();
       }
    }


   @Override
   public void run() {
       while (true){
           try {
               Mensaje m= (Mensaje) fIn.readObject();
               TipoMensaje type = m.getTipo();
               switch (type) {
               case Conexion:
                   Usuario usr= new Usuario(((MensajeConexion) m).getUserName());
                servidor.registra(usr);
                servidor.guardaFlujo(usr,fOut);
                MensajeConfirmacion confirmacion = new MensajeConfirmacion(m.getDestino(),m.getOrigen());
                fOut.writeObject(confirmacion);
               break;
               case ListaUsuarios:
                /*
                 * -buscar info en tUsuarios
                 * -mandar msge conf lista usuarios
                 * */
               break;
               case EmitirFichero:
                /*
                 * -obtener info usuario que tiene fichero
                 * -mandar mensaje peticion fichero
                 * 
                 * */
               break;
               case PrepComCS:
                /*
                 * mandar mensaje preparar comunicacion SC
                 * */
               break;
               default:
                   System.err.println(m);
               break;
               }    
           }  
           catch (ClassNotFoundException e) {
               e.printStackTrace();
           }
           catch (IOException e) {  
               e.printStackTrace();
           }
       }
   }
}
服务器侦听器

public class OyenteServidor extends Thread{
private Socket myS;
private ObjectInputStream fIn;
private ObjectOutputStream fOut;
private Cliente client;

public OyenteServidor(Socket s,Cliente clie) {
    client=clie;
    try {
        myS=s;
        fIn=new ObjectInputStream(myS.getInputStream());//<---Client thread stops here
        fOut=new ObjectOutputStream(myS.getOutputStream());
    } 
    catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}
@Override
public void run(){
    while (true){
        try {
            Mensaje m = (Mensaje) fIn.readObject();
            TipoMensaje type=m.getTipo();
            switch (type) {
            case ConfConexion:
                client.print("Conexión confirmada");
            break;
            case ConfListaUsuarios:
            break;
            case PetFichero:
            break;
            case PrepComCS:
            break;
            default:
            break;
            }
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
我必须通过传递MessagesConnectionRequest、FileRequest实现通信。。因此,当我创建每个套接字时,我会尝试在每个侦听器中使用ObjectInputStream和ObjectOutputStream来实现这一点

调试Cliente和Servidor我刚刚发现,当它们使用Socket.getInputStream初始化ObjectInputStream时,这两个进程都会永远暂停

谁能告诉我我错了多少


多谢各位

发生这种情况是因为ObjectInputStream的ctor阻塞。请看下面的图片。也许您应该使用另一个Inputstream,如BufferedInputStream。

您需要在ObjectInputStream之前构造ObjectOutputStream

您还需要在两端构造相同的流。你现在的混流行不通


如果希望在多个线程中使用,还需要在整个过程中删除关键字static。

谢谢这两个答案。足够好让我继续我的项目。 我就是这样解决的。我将我的解决方案分享给任何可能感兴趣的人,或者任何想教我其他东西的人

ClientListener:

public class OyenteCliente extends Thread {
private Servidor servidor;
private Socket s;   
private ObjectInputStream fIn;
private ObjectOutputStream fOut;
public OyenteCliente(Socket so,Servidor ser) {
    servidor=ser;
    s=so;
    try {
        fOut=new ObjectOutputStream(s.getOutputStream());
        fIn=new ObjectInputStream(s.getInputStream());
    } 
    catch (IOException e) {
        e.printStackTrace();
    }
}


@Override
public void run() {
    while (true){
        try {
            Mensaje m= (Mensaje) fIn.readObject();
            TipoMensaje type = m.getTipo();
            switch (type) {
            case Conexion:
                Usuario usr= new Usuario(((MensajeConexion) m).getUserName());
                //-Guardar en tUsuarios info nuevo usuario
                servidor.registra(usr);
                /* -Guardar en tCanales flujo de comunicacion   * */
                servidor.guardaFlujo(usr,fOut);
                MensajeConfirmacion confirmacion = new MensajeConfirmacion(m.getDestino(),m.getOrigen());
                fOut.writeObject(confirmacion);
            break;
            case ListaUsuarios:
                /*
                 * -buscar info en tUsuarios
                 * -mandar msge conf lista usuarios
                 * */
            break;
            case EmitirFichero:
                /*
                 * -obtener info usuario que tiene fichero
                 * -mandar mensaje peticion fichero
                 * 
                 * */
            break;
            case PrepComCS:
                /*
                 * mandar mensaje preparar comunicacion SC
                 * */
            break;
            default:
                System.err.println(m);
            break;
            }   
        } 
        catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        catch (IOException e) { 
            e.printStackTrace();
        }
    }
}
}

服务器侦听器:

public class OyenteServidor extends Thread{
private Socket myS;
private ObjectInputStream fIn;
private ObjectOutputStream fOut;
private Cliente client;

public OyenteServidor(Socket s,Cliente clie) {
    client=clie;
    myS=s;
    try {
        fOut=new ObjectOutputStream(myS.getOutputStream());
        fIn=new ObjectInputStream(myS.getInputStream());
        fOut.writeObject(new MensajeConexion(clie.getIp(), 
                myS.getInetAddress().getHostAddress(), client.getName()));
    } 
    catch (IOException e) {
        e.printStackTrace();
    }
}
@Override
public void run(){
    while (true){
        try {
            Mensaje m = (Mensaje) fIn.readObject();
            TipoMensaje type=m.getTipo();
            switch (type) {
            case ConfConexion:
                client.print("Conexión confirmada");
            break;
            case ConfListaUsuarios:
            break;
            case PetFichero:
            break;
            case PrepComCS:
            break;
            default:
            break;
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
 }
}