2011-12-04 7 views
7


서버와 통신하기 위해 클래스를 프로그래밍하고 있지만 InputStream의 도움으로 ObjectInputStream을 구성하려고하면 프로그램이 멈 춥니 다. theres는 예외가 아니며 프로그램은 여전히 ​​실행 중이지만 ObjectInputstream을 생성하려고 시도하는 행에 매달려 있습니다.ObjectInputStream (socket.getInputStream()); does not work

을 Heres

내 문제가있는 메서드의 코드 :

@Override 
public void connect(String ip, int port) throws UnknownHostException, IOException { 
    Socket socket = new Socket(ip, port); 
    out = new ObjectOutputStream(socket.getOutputStream()); 
    InputStream is = socket.getInputStream(); 
    in = new ObjectInputStream(is); 
} 

이 전체 클래스의 코드입니다 :

package Client; 

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.io.ObjectInputStream; 
import java.io.ObjectOutputStream; 
import java.io.PrintWriter; 
import java.net.Socket; 
import java.net.UnknownHostException; 


public class MessageStreamerImpl implements MessageStreamer { 
    ObjectOutputStream out; 
    ObjectInputStream in; 

    public MessageStreamerImpl(String ip, int port) throws UnknownHostException, IOException{ 
     connect(ip, port); 
    } 

    public MessageStreamerImpl(){ 
    } 

    @Override 
    public void send(Object message) throws IOException { 
     if(out == null) throw new IOException(); 
     out.writeObject(message); 
     out.flush(); 
    } 

    @Override 
    public Object receive() throws IOException{ 
     try { 
      return in.readObject(); 
     } catch (ClassNotFoundException e) { 
      throw new IOException(); 
     } 
    } 

    @Override 
    public void connect(String ip, int port) throws UnknownHostException, IOException { 
     Socket socket = new Socket(ip, port); 
     out = new ObjectOutputStream(socket.getOutputStream()); 
     InputStream is = socket.getInputStream(); 
     in = new ObjectInputStream(is); 
    } 

} 

구글을 보면서 내가 이걸 발견 : http://www.coderanch.com/t/232944/threads/java/Socket-getInputStream-block. 그러나 ObjectOutputStream 생성자가 ObjectInputStream의 생성자보다 먼저 있기 때문에 문제를 해결하는 방법을 아직 모릅니다. 당신의 도움에 대한

package Server; 

import java.io.IOException; 
import java.io.ObjectInputStream; 
import java.io.ObjectOutputStream; 
import java.net.ServerSocket; 
import java.net.Socket; 
import java.net.SocketException; 
import java.util.ArrayList; 

public class Server { 
    ArrayList<Socket> clients = new ArrayList<Socket>(); 

    public Server(int port){ 
     try { 
      ServerSocket mySocket = new ServerSocket(port); 
      waitForClients(mySocket); 
     } catch (IOException e) { 
      System.out.println("Unable to start."); 
      e.printStackTrace(); 
     } 
    } 

    private void waitForClients(ServerSocket mySocket) { 
     while(true){ 
      try { 
       System.out.println("Ready to receive"); 
       Socket client = mySocket.accept(); 
       clients.add(client); 
       System.out.println(client.getInetAddress().getHostAddress()+" connected to the Server"); 
       Thread t = new Thread(new ClientHandler(client)); 
       t.start(); 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 
    } 

    public void shareToAll(Object objectToSchare){ 
     for(Socket client:clients){ 
      ObjectOutputStream oos; 
      try { 
       oos = new ObjectOutputStream(client.getOutputStream()); 
       oos.writeObject(objectToSchare); 
       oos.close(); 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 
    } 

    private class ClientHandler implements Runnable{ 
     Socket clientSocket; 

     public ClientHandler(Socket clientSocket){ 
      this.clientSocket = clientSocket; 
     } 
     @Override 
     public void run() { 
      try { 
       ObjectInputStream ois = new ObjectInputStream(clientSocket.getInputStream()); 
       while(true){ 
        try { 
         ois.readObject(); 

        } catch (ClassNotFoundException | IOException e) { 
         // TODO Auto-generated catch block 
         e.printStackTrace(); 
        } 
       } 
      }catch(SocketException e){ 
       System.out.println(clientSocket.getInetAddress().getHostAddress()+" disconnected from the Server"); 
       clients.remove(clientSocket); 
      }catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 
    } 
} 

덕분에 나는 오류를 발견)

여기에 어쩌면 도움이 될 것입니다, 내 서버 코드입니다. 그것은 다음과 같이해야하는 서버 클래스에 있었다 :

package Server; 

import java.io.IOException; 
import java.io.ObjectInputStream; 
import java.io.ObjectOutputStream; 
import java.net.ServerSocket; 
import java.net.Socket; 
import java.net.SocketException; 
import java.util.ArrayList; 

public class Server { 
    ArrayList<ObjectOutputStream> clientstreams = new ArrayList<ObjectOutputStream>(); 

    public Server(int port){ 
     try { 
      ServerSocket mySocket = new ServerSocket(port); 
      waitForClients(mySocket); 
     } catch (IOException e) { 
      System.out.println("Unable to start."); 
      e.printStackTrace(); 
     } 
    } 

    private void waitForClients(ServerSocket mySocket) { 
     while(true){ 
      try { 
       System.out.println("Ready to receive"); 
       Socket client = mySocket.accept(); 
       clientstreams.add(new ObjectOutputStream(client.getOutputStream())); 
       System.out.println(client.getInetAddress().getHostAddress()+" connected to the Server"); 
       Thread t = new Thread(new ClientHandler(client)); 
       t.start(); 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 
    } 

    public void shareToAll(Object objectToSchare){ 
     for(ObjectOutputStream stream:clientstreams){ 
      try { 
       stream.writeObject(objectToSchare); 
       stream.flush(); 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 
    } 

    private class ClientHandler implements Runnable{ 
     Socket clientSocket; 

     public ClientHandler(Socket clientSocket){ 
      this.clientSocket = clientSocket; 
     } 
     @Override 
     public void run() { 
      try { 
       ObjectInputStream ois = new ObjectInputStream(clientSocket.getInputStream()); 
       while(true){ 
        try { 
         ois.readObject(); 

        } catch (ClassNotFoundException | IOException e) { 
         // TODO Auto-generated catch block 
         e.printStackTrace(); 
        } 
       } 
      }catch(SocketException e){ 
       System.out.println(clientSocket.getInetAddress().getHostAddress()+" disconnected from the Server"); 
       clientstreams.remove(clientSocket); 
      }catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 
    } 
} 

가장 당신이 방법 waitForClients()에서 참조 변경하지만 변경, 너무 내 ArrayList의 개념과 shareToAll 방법.

답변

12

ObjectInputStream 생성자는 지정된 InputStream에서 데이터를 읽습니다. 이 작업을 수행하려면 은 ObjectInputStream을 열려고 시도하기 전에 초기 헤더를 작성하기 위해 Construct 후 바로 ObjectOutputStream을 플러시해야합니다. 또한 연결 당 둘 이상의 객체를 보내려면 ObjectOutputStream을 한 번 열어 소켓 수명 동안 사용해야합니다 (예 : shareToAll 메소드).

+0

당신이 같은지 모르겠지만 이유를 찾았습니다. faul은 waitForClients() 메서드에서 서버 클래스에있었습니다. 소켓 클라이언트 = mySocket.accept(); 후에 Outputstream을 생성해야했습니다. client.getOutputstream();과 함께. 그렇지 않으면, 클라이언트는 OutputStream (그의 InputStream)을 기다리는 것을 막는다. 감사합니다. –

+0

아직 내 질문에 대답 할 수 없기 때문에 질문을 편집했습니다. –

+0

계속해서 입출력 스트림을 매번 다시 정의하면 안됩니다. 그들은'ClientHandler' 클래스 안에서 전역 적이어야합니다. – Jon