2016-10-20 3 views
1

私は基本的なチャットアプリを持っています。 server、client、およびclientHandlerの3つのクラスがあります。問題は、サーバーが(DataInputStreamを使用して)初めて読み取ることができ、次に例外をスローすることができることです。Java DataOutputSreamは一度だけ動作します

Hello. I have a basic chat app. There are 3 classes: server, client and clientHandler. The problem is that server is able to read (using DataInputStream) only first time then it throws exceptions. 

Client.java:

package Client; 

import javax.swing.JFrame; 

import javax.swing.JPanel; 
import javax.swing.border.EmptyBorder; 
import javax.swing.JTextArea; 

import javax.swing.JButton; 
import javax.swing.JTextField; 
import java.awt.event.ActionListener; 

import java.io.DataInputStream; 
import java.io.DataOutputStream; 
import java.io.IOException; 

import java.net.Socket; 
import java.net.UnknownHostException; 
import java.awt.event.ActionEvent; 
import javax.swing.JScrollPane; 
import javax.swing.JLabel; 
import javax.swing.JOptionPane; 


public class Client extends JFrame{ 

private JPanel contentPane; 
private JTextField tf_input; 
private static JTextArea ta_chat; 
private JButton b_connect; 


private static int portNumber = 2309; 
private static String ip = null; 
private JScrollPane scrollPane; 
private JTextField tf_ip; 


private Socket s = null; 
private DataOutputStream dos = null; 
private DataInputStream dis = null; 
private JTextField tf_port; 


private boolean connected = false; 
private JLabel lblIp; 
private JLabel lblPort; 
private JLabel lblName; 
private JTextField tf_name; 
private JButton btnDc; 


/** 
* Launch the application. 
*/ 
public static void main(String[] args) { 

    Client frame = new Client(); 
    frame.setVisible(true); 


    System.out.println("Client is running!"); 


    // TODO Auto-generated method stub 



    //Listening to server 

    while(!frame.connected) 
    { 
     System.out.println("Waiting...!"); 
    } 

    while(true) 
    { 
     System.out.println("Listening started!"); 
     String line = null; 

     try { 
      line = frame.dis.readUTF(); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
      ta_chat.append("reading from server failed\n"); 
      //System.out.println(Thread.currentThread().getName() + " failed listening to server!\n"); 
     } 

     if(line!=null) 
      ta_chat.append(line.trim() + "\n"); 
    } 
} 

    // 


/** 
* Create the frame. 
*/ 
public Client() { 
    setTitle("Client"); 
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    setBounds(100, 100, 530, 458); 
    contentPane = new JPanel(); 
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); 
    setContentPane(contentPane); 
    contentPane.setLayout(null); 

    JButton b_send = new JButton("Send"); 
    b_send.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent arg0) { 
      if(!connected) 
      { 
       JOptionPane.showMessageDialog(null, "You have to connect first!"); 
       return; 
      } 

      String message = tf_input.getText(); 

      try { 
       ta_chat.append("writing UTF" + '\n'); 
       dos.writeUTF(message); 
       ta_chat.append(ta_chat.getText().trim() + "writing UTF succeded" + '\n'); 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       ta_chat.append(ta_chat.getText().trim() + "writing UTF failed" + '\n'); 
      } 

      tf_input.setText(null); 
     } 
    }); 
    b_send.setBounds(375, 204, 89, 23); 
    contentPane.add(b_send); 

    tf_input = new JTextField(); 
    tf_input.setBounds(89, 205, 258, 20); 
    contentPane.add(tf_input); 
    tf_input.setColumns(10); 

    scrollPane = new JScrollPane(); 
    scrollPane.setBounds(39, 11, 452, 175); 
    contentPane.add(scrollPane); 

    ta_chat = new JTextArea(); 
    scrollPane.setViewportView(ta_chat); 
    ta_chat.setEditable(false); 

    b_connect = new JButton("Connect"); 
    b_connect.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent ae) { 

      connected = true; 

      String ip = tf_ip.getText(); 
      String name = tf_name.getText(); 
      int portNumber = Integer.parseInt(tf_port.getText()); 

      try { 
       s = new Socket(ip, portNumber); 
       ta_chat.append("s=" + s + "\n"); 
      } catch (UnknownHostException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 

      try { 
       dis = new DataInputStream(s.getInputStream()); 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
       ta_chat.append("dis init failed\n"); 
      } 

      try { 
       dos = new DataOutputStream(s.getOutputStream()); 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
       System.out.println("DataOutputStraem object init failed!"); 
       ta_chat.append("dos init failed\n"); 
      } 

      try 
      { 
       dos.writeUTF("/name " + name); 
      } 
      catch(Exception e) 
      { 
       ta_chat.append("dos.writeUTF() failed \n"); 
      } 
     } 
    }); 
    b_connect.setBounds(89, 373, 89, 23); 
    contentPane.add(b_connect); 

    tf_ip = new JTextField(); 
    tf_ip.setBounds(83, 269, 123, 20); 
    contentPane.add(tf_ip); 
    tf_ip.setColumns(10); 

    tf_port = new JTextField(); 
    tf_port.setColumns(10); 
    tf_port.setBounds(83, 300, 123, 20); 
    contentPane.add(tf_port); 

    lblIp = new JLabel("IP:"); 
    lblIp.setBounds(39, 272, 46, 14); 
    contentPane.add(lblIp); 

    lblPort = new JLabel("Port"); 
    lblPort.setBounds(39, 303, 46, 14); 
    contentPane.add(lblPort); 

    lblName = new JLabel("Name:"); 
    lblName.setBounds(39, 335, 46, 14); 
    contentPane.add(lblName); 

    tf_name = new JTextField(); 
    tf_name.setColumns(10); 
    tf_name.setBounds(83, 332, 123, 20); 
    contentPane.add(tf_name); 

    btnDc = new JButton("dc"); 
    btnDc.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent arg0) { 
      try { 
       dis.close(); 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
      try { 
       dos.close(); 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 

      try { 
       s.close(); 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 
    }); 
    btnDc.setBounds(290, 373, 89, 23); 
    contentPane.add(btnDc); 

} 

}

Server.java:

package Server; 
import java.awt.EventQueue; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.net.InetAddress; 
import java.net.MalformedURLException; 
import java.net.ServerSocket; 
import java.net.Socket; 
import java.net.URL; 

import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JOptionPane; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.JTextArea; 
import javax.swing.JTextField; 
import javax.swing.border.EmptyBorder; 

public class Server extends JFrame{ 

private JPanel contentPane; 
private JTextField tf_input; 

private static int portNumber = 2309; 
private static JTextArea ta_ServerLog; 
private JTextField tf_IP; 
private JButton btnRefresh; 
private JTextField textField; 
private JLabel lblPort; 
private static ServerSocket ss = null; 

/** 
* Launch the application. 
*/ 

public static void addTextToServerLog(String text) 
{ 
    if(text.equals(null)) 
     return; 
    else 
     ta_ServerLog.setText(ta_ServerLog.getText().trim() + "\n" + text.trim()); 
} 

public static void main(String[] args) { 
    EventQueue.invokeLater(new Runnable() { 
     public void run() { 
      try { 
       Server frame = new Server(); 
       frame.setVisible(true); 
      } catch (Exception e) { 

      } 
     } 
    }); 


    try { 
     ss = new ServerSocket(portNumber); 
    } catch (IOException e1) { 
     // TODO Auto-generated catch block 
    } 


    while(true) 
    { 
     Socket s = null; 
     try { 
      s = ss.accept(); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 

     } 

     System.out.println("Creating new ClientListener!"); 
     new ClientHandler(s).start(); 
    } 

} 

/** 
* Create the frame. 
*/ 
public Server() { 
    setTitle("Server"); 
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    setBounds(100, 100, 450, 377); 
    contentPane = new JPanel(); 
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); 
    setContentPane(contentPane); 
    contentPane.setLayout(null); 

    tf_input = new JTextField(); 
    tf_input.setBounds(125, 209, 109, 20); 
    contentPane.add(tf_input); 
    tf_input.setColumns(10); 

    JButton b_send = new JButton("Send"); 
    b_send.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
     } 
    }); 
    b_send.setBounds(278, 209, 86, 20); 
    contentPane.add(b_send); 

    JScrollPane scrollPane = new JScrollPane(); 
    scrollPane.setBounds(49, 26, 294, 136); 
    contentPane.add(scrollPane); 

    ta_ServerLog = new JTextArea(); 
    ta_ServerLog.setEditable(false); 
    scrollPane.setViewportView(ta_ServerLog); 

    JLabel lblYouAreHosting = new JLabel("Your IP:"); 
    lblYouAreHosting.setBounds(49, 277, 44, 14); 
    contentPane.add(lblYouAreHosting); 

    tf_IP = new JTextField(); 
    tf_IP.setEditable(false); 
    tf_IP.setBounds(96, 274, 103, 20); 
    contentPane.add(tf_IP); 
    tf_IP.setColumns(10); 

    btnRefresh = new JButton("Refresh IP"); 
    btnRefresh.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
      tf_IP.setText(getIP()); 
     } 
    }); 
    btnRefresh.setBounds(212, 273, 89, 23); 
    contentPane.add(btnRefresh); 

    textField = new JTextField(); 
    textField.setText(Integer.toString(portNumber)); 
    textField.setColumns(10); 
    textField.setBounds(96, 305, 103, 20); 
    contentPane.add(textField); 

    lblPort = new JLabel("Port:"); 
    lblPort.setBounds(49, 308, 44, 14); 
    contentPane.add(lblPort); 

    JButton btnNewButton = new JButton("dc"); 
    btnNewButton.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent arg0) { 
      ss = null; 
     } 
    }); 
    btnNewButton.setBounds(10, 185, 51, 23); 
    contentPane.add(btnNewButton); 
} 

private String getIP() 
{ 
    URL site = null; 
    try { 
     site = new URL("http://checkip.amazonaws.com"); 
    } catch (MalformedURLException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

    BufferedReader reader = null; 
    try { 
     reader = new BufferedReader(new InputStreamReader(site.openStream())); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

    try 
    { 
     return InetAddress.getLocalHost().getHostAddress().toString(); 
     //return reader.readLine(); 
    } 
    catch(Exception e) 
    { 

    } 

    return null; 
} 

}

ClientHandler.java:

package Server; 
import java.awt.HeadlessException; 
import java.io.BufferedReader; 
import java.io.DataInputStream; 
import java.io.DataOutputStream; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.net.MalformedURLException; 
import java.net.Socket; 
import java.net.URL; 
import java.util.ArrayList; 

import javax.swing.JOptionPane; 


public class ClientHandler extends Thread{ 

private Socket clientSocket = null; 
private DataInputStream dis = null; 
private static ArrayList<Socket> users = null; 


private String getIP() 
{ 
    URL website = null; 
    try { 
     website = new URL("http://checkip.amazonaws.com"); 
    } catch (MalformedURLException e1) { 
     // TODO Auto-generated catch block 
     e1.printStackTrace(); 
    } 

    BufferedReader reader = null; 
    try { 
     reader = new BufferedReader(new InputStreamReader(website.openStream())); 
    } catch (IOException e1) { 
     // TODO Auto-generated catch block 
     e1.printStackTrace(); 
    } 

    try { 
     return reader.readLine(); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    return null; 
} 


public ClientHandler(Socket clientSocket) 
{ 

    this.clientSocket = clientSocket; 

    if(users==null) 
     users = new ArrayList<Socket>(); 

    try 
    { 
     users.add(clientSocket); 
    } 
    catch(Exception ex) 
    { 
     System.out.println("Adding client's socket to socket list failed!"); 
    } 


    try 
    { 
     dis = new DataInputStream(clientSocket.getInputStream()); 
    } 
    catch(Exception e) 
    { 

    } 

    Server.addTextToServerLog("Trying to add a new client!"); 
    /* 
    try { 
     Thread.sleep(5000); 
    } catch (InterruptedException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    */ 
    Server.addTextToServerLog("Client added!"); 
} 

public void tellEveryone(String message, String name) 
{ 
    for (Socket socket : users) { 
     Socket s = socket; 

     try { 
      DataOutputStream dos = new DataOutputStream(s.getOutputStream()); 
      dos.writeUTF(name + ":" + message); 

      dos.close(); 
     } catch (IOException e1) { 
      // TODO Auto-generated catch block 
      e1.printStackTrace(); 
     } 
    } 
} 

public void disconnect() 
{ 

} 


// reciving messages from a specific client and send to everyone else 
public void run() 
{ 
    while(true) 
    { 
     String line = null; 

     try { 
      System.out.println("Reading client input"); 

      Server.addTextToServerLog("-line-"); 
      try { 
       Thread.sleep(1000); 
      } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
      line = dis.readUTF(); 
      Server.addTextToServerLog("Line=" + line); 

      if(line!=null) 
      { 

       if(line.startsWith("/name ")) 
       { 
        String name = line.replaceFirst("/name", ""); 
        tellEveryone("joined room!", name); 
        Server.addTextToServerLog(name + "joined room!"); 
       } 
       else 
       { 
        tellEveryone(line, null); 
        Server.addTextToServerLog(line); 
       } 

      } 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
     } 

    } 
} 

}

、第2の試行から例外をスロー:(Client.java - 送信ボタンが押されたときに、これが実行される)

b_send.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent arg0) { 
      if(!connected) 
      { 
       JOptionPane.showMessageDialog(null, "You have to connect first!"); 
       return; 
      } 

      String message = tf_input.getText(); 

      try { 
       ta_chat.append("writing UTF" + '\n'); 
       dos.writeUTF(message); 
       ta_chat.append(ta_chat.getText().trim() + "writing UTF succeded" + '\n'); 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       ta_chat.append(ta_chat.getText().trim() + "writing UTF failed" + '\n'); 
      } 

      tf_input.setText(null); 
     } 
    }); 

Server.java:(この部分は関連するかもしれません1)

while(true) 
    { 
     Socket s = null; 
     try { 
      s = ss.accept(); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 

     } 

     System.out.println("Creating new ClientListener!"); 
     new ClientHandler(s).start(); 
    } 

ClientHandler.run():

public void run() 
{ 
    while(true) 
    { 
     String line = null; 

     try { 
      System.out.println("Reading client input"); 

      Server.addTextToServerLog("-line-"); 
      try { 
       //Thread.sleep(1000); 
      } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
      line = dis.readUTF(); // <----------- this works only 1st time 
      Server.addTextToServerLog("Line=" + line); 

      if(line!=null) 
      { 

       if(line.startsWith("/name ")) 
       { 
        String name = line.replaceFirst("/name", ""); 
        tellEveryone("joined room!", name); 
        Server.addTextToServerLog(name + "joined room!"); 
       } 
       else 
       { 
        tellEveryone(line, null); 
        Server.addTextToServerLog(line); 
       } 

      } 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
     } 

    } 
} 

私はアプリがもう少し前に働いたと言わねばならないが、それは並行性の問題を抱えていたが、十分に機能していた。私にはバックアップがありません。問題の

+0

例外スタックトレース全体を投稿します。 –

答えて

1

少なくとも一部は、クライアントのtellEveryone(2)方法である:

DataOutputStream dos = new DataOutputStream(s.getOutputStream()); 
dos.writeUTF(name + ":" + message); 
dos.close(); 

あなたがストリームにメッセージを送信するたびに閉じています。 dosは、クライアントのSocketインスタンスの出力ストリームを使用して作成されるため、dosclose()メソッドを呼び出すたびにソケットを閉じます。おそらくdosをクライアントクラスのメンバ変数として格納し、本当に切断したいときにのみ閉じてください。

さらに、メッセージ全体をソケットに書き込むために、メッセージを送信するたびにdos.flush()に電話する必要があります。場合によっては、OutputStreamの実装では、特定のバッファサイズに達するまでデータをキャッシュし、そのバッファ全体を基礎となるストリームにフラッシュすることがあります(この場合、基本ストリームはソケット自体です)。 flush()に電話しないと、バッファリングのためにメッセージの一部がソケットに書き込まれない可能性があります。

本当に切断しない限り、開いているソケットを閉じていないことをコード全体で確認してください。これにより、問題が解決される可能性があります。

+0

はい。私は削除しました: – Radu

+0

私はdos.close()を削除しました。今、サーバーはメッセージを受信して​​います。しかし、クライアントがサーバーからの入力を受け取っていないこともあります。それは無作為なようです。 – Radu

+0

そのクライアントはサーバーからメッセージを受信しなくても、サーバーに送信でき、他のクライアント(そのサーバー)に再生することができます。クライアントが一度もメッセージを受信しなかった場合、彼は決してこれを行いません。私は一部のクライアントが働いているが、他の人はサーバーの出力を得ることができないということです。 – Radu

関連する問題