2015-05-23 209 views
1

我正在尝试为多个客户端和单个服务器编写类似聊天的应用程序。想法:客户端发送字符串到服务器,服务器与它一起工作并返回到客户端对象(只有客户端发送字符串接收答案!)。多个客户端“聊天”

问题:单个客户端运行良好。运行第二个客户端会产生麻烦:客户端2接收到客户端1的回答,并且在第一个回答后两个客户端都无法发送任何内容

换句话说,我需要帮助。

下面是代码: 服务器:

public class serverWindow extends JFrame { 

private JPanel contentPane; 
private static JTextField tfAddition; 
static JTextPane tp; 

// connection stuff 
static ServerSocket ss = null; 
static Socket soc = null; 
static DataInputStream din; 
static ObjectOutputStream obout; 
static int port = 1255; 

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

    try 
    { 
     ss = new ServerSocket(port);  
     while(true) 
     { 
      try 
      { 
       soc = ss.accept();    
       echoThread X = new echoThread(soc, tp); 
       X.start(); 
      } 
      catch(Exception ex) 
      { 
       ex.printStackTrace(); 
      } 
     } 
    } 
    catch(Exception ex) 
    { 
     ex.printStackTrace(); 
    } 
    finally 
    { 
     ss.close(); 
    } 
} 

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

    JScrollPane scrollPane = new JScrollPane(); 
    scrollPane.setBounds(10, 11, 414, 183); 
    contentPane.add(scrollPane); 

    tp = new JTextPane(); 
    tp.setEditable(false); 
    scrollPane.setViewportView(tp); 
} 
} 

echoThread:

public class echoThread extends Thread 
{ 
protected Socket soc; 
public JTextPane tp; 
static DataInputStream din = null; 
static ObjectOutputStream obout = null; 

public echoThread(Socket soc, JTextPane tp) 
{ 
    this.soc = soc; 
    this.tp = tp; 
} 

public void run() 
{ 
    try 
    { 
     din = new DataInputStream(this.soc.getInputStream()); 
     obout = new ObjectOutputStream(soc.getOutputStream()); 

     while(true) 
     { 
      String message = din.readUTF();       
      tp.setText(tp.getText().trim() + "\n" + message); 
      Response res = new Response(message, message.length()); 
      obout.writeObject(res); 
      obout.flush(); 
     } 
    } 
    catch(Exception ex) 
    { 
     ex.printStackTrace(); 
     return; 
    } 
    finally 
    { 
     try 
     { 
      soc.close(); 
      din.close(); 
      obout.close(); 
     } 
     catch(Exception ex) 
     { 
      ex.printStackTrace(); 
      return; 
     } 
    } 
} 
} 

客户端:

public class clientW extends JFrame { 

private JPanel contentPane; 
private JTextField textField; 
private static JTextPane textPane; 

// sockets 
static Socket soc = null; 
static ObjectInputStream obin = null; 
static DataOutputStream dout = null; 
static int port = 1255; 
static String host = "localhost"; 

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

    try 
    { 
     try 
     { 
      soc = new Socket(host, port); 
      dout = new DataOutputStream(soc.getOutputStream()); 
      obin = new ObjectInputStream(soc.getInputStream()); 
      while(true) 
      { 
       Response res = (Response) obin.readObject(); 
       textPane.setText(textPane.getText().trim() + "\n" + res.combineText()); 
      } 
     } 
     catch(Exception ex) 
     { 
      ex.printStackTrace(); 
     } 

    } 
    catch(Exception ex) 
    { 
     ex.printStackTrace(); 
    }   
    finally 
    { 
     soc.close(); 
     obin.close(); 
     dout.close(); 
    } 
} 

public clientW() { 
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    setBounds(100, 100, 450, 300); 
    contentPane = new JPanel(); 
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); 
    setContentPane(contentPane); 
    contentPane.setLayout(null); 

    JButton btnNewButton = new JButton("send"); 
    btnNewButton.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent arg0) 
     { 
      try 
      { 
       dout.writeUTF(textField.getText().trim()); 
       dout.flush(); 
      } 
      catch(Exception ex) 
      { 
       ex.printStackTrace(); 
      } 
     } 
    }); 
    btnNewButton.setBounds(335, 227, 89, 23); 
    contentPane.add(btnNewButton); 

    textField = new JTextField(); 
    textField.setBounds(10, 227, 315, 21); 
    contentPane.add(textField); 
    textField.setColumns(10); 

    textPane = new JTextPane(); 
    textPane.setEditable(false); 
    textPane.setBounds(10, 11, 414, 205); 
    contentPane.add(textPane); 
} 
} 

回答

1

DIN和obout在echoThread被声明为静态变量,因此他们在所有的客户之间共享。这可以通过声明din和obout而不用static关键字来纠正。这是否解决了它?

+0

它的确如此。谢谢。 –

1

您正在将echoThread中的流定义为静态,这意味着该类的所有实例都将共享这些对象。因此,当第二个echoThread实例启动时,它会覆盖第一个实例的流,因此一个套接字的流将丢失。如果您将定义更改为:

private DataInputStream din = null; 
private ObjectOutputStream obout = null; 

它看起来像您所描述的那样工作。