2011-12-04 21 views
7


私はサーバーと通信するクラスをプログラミングしていますが、入力ストリームの助けを借りてObjectInputStreamを構築しようとすると、プログラムはフリーズしています。 Theresは例外ではなく、プログラムはまだ実行中ですが、ObjectInputstreamを構築しようとしている行にぶら下がっています。ObjectInputStream(socket.getInputStream()); does not work

相続人は私の問題が配置されているメソッドのコード:

@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

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); 
    } 

} 

Googleのを見ながら、私はこれを見つけました。しかし、私は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をオープンしようとする前に、(初期ヘッダーを書き込むために)コンストラクション直後にObjectOutputStreamをフラッシュする必要があります。また、接続ごとに複数のオブジェクトを送信する場合は、ObjectOutputStreamを一度開いてソケットの有効期間(例:shareToAllメソッド)で使用する必要があります。

+0

同じことがあったかどうかわかりませんが、その理由がわかりました。 faulは、waitForClientsメソッドのサーバークラスにありました.Socketクライアント= mySocket.accept();の後にOutputstreamを生成する必要があります。 client.getOutputstream();を使用します。さもなければ、クライアントはOutputStream(彼のInputStream)を待ってブロックされます。ありがとうございます –

+0

私は自分の質問にまだ答えることができないので、質問を編集しました。 –

+0

あなたはまだ入力ストリームと出力ストリームを毎回再定義するべきではありません。それらは 'ClientHandler'クラスの中でグローバルでなければなりません。 – Jon

関連する問題