繁体   English   中英

在Client Class中创建ObjectInputStream时为什么会卡住? (套接字编程)

[英]Why it stucks while creating ObjectInputStream in Client Class ? (Socket Programming)

当我在我的服务器 - 客户端程序中使用DataOutputStream / DataInputStream时一切顺利,但在我决定使用ObjectInputStream / ObjectOutputStream之前,我在创建ObjectInputStream / ObjectOutputStream时遇到了问题。 我和我的朋友看不出问题出在哪里。 如果有人有任何想法,那将是感恩的。 这是我的“MyClient”和“MultiThreadServer”类。

它完全停留在这一行:“fromServer = new ObjectInputStream(s.getInputStream());” MyClient类中的行。

这是我的“MyClient”类:

public class MyClient extends javax.swing.JFrame {

String name;
public MyClient() {
    initComponents();
    sendButton.addActionListener(new ButtonListener());
    jTextField1.addActionListener(new ButtonListener());

    try{
        Socket s = new Socket("localhost", 8080);               // program reaches to this step
        fromServer = new ObjectInputStream(s.getInputStream()); // and gets stuck in this step. (Understand it with using some Sys.out.print();)
        toServer = new ObjectOutputStream(s.getOutputStream());         
    }
    catch(Exception ex){
        System.out.println("Something happend while socket is creating!");
    }
}

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
   name = jTextField2.getText();
}                                        

public static void main(String args[]) {

    try {
        for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
            if ("Windows".equals(info.getName())) {
                javax.swing.UIManager.setLookAndFeel(info.getClassName());
                break;
            }
        }
    } catch (ClassNotFoundException ex) {
        java.util.logging.Logger.getLogger(MyClient.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (InstantiationException ex) {
        java.util.logging.Logger.getLogger(MyClient.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (IllegalAccessException ex) {
        java.util.logging.Logger.getLogger(MyClient.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (javax.swing.UnsupportedLookAndFeelException ex) {
        java.util.logging.Logger.getLogger(MyClient.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    }

    /* Create and display the form */
    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            new MyClient().setVisible(true); 
        }
    });
}

private ObjectOutputStream toServer;
private ObjectInputStream fromServer;

private class ButtonListener implements ActionListener{

    @Override
    public void actionPerformed(ActionEvent ae) {

        // Here there are some activities when the button is clicked. 


    }

}
}

这是我的“MutliThreadServer”类:

public class MultiThreadServer  {

private String secretWord;
public Socket s;
public ArrayList clients = new ArrayList<ObjectOutputStream>();
ServerSocket serverSocket;

public static void main(String[] args) {  
  new MultiThreadServer();   
}

public MultiThreadServer() {

try {
  serverSocket = new ServerSocket(8080);
  System.out.println("MultiThreadServer started at " + new Date() + '\n');

  int clientNo = 1;

  while (true) {

     s = serverSocket.accept(); 

    System.out.println("Starting thread for client " + clientNo +" at " + new Date() + '\n');

    InetAddress inetAddress = s.getInetAddress();
    System.out.println("Client " + clientNo + "'s host name is "+ inetAddress.getHostName() + "\n");
    System.out.println("Client " + clientNo + "'s IP Address is "+ inetAddress.getHostAddress() +     "\n");

    HandleAClient task = new HandleAClient(s);

    new Thread(task).start();

    clientNo++;
   }
 }
catch(IOException ex) {
  System.err.println(ex);
 }
}

class HandleAClient implements Runnable {
private Socket socket;

public HandleAClient(Socket socket) {
  this.socket = socket;
}

/** Run a thread */
public void run() {

  try {
    ObjectInputStream inputFromClient = new ObjectInputStream(
      socket.getInputStream());
    ObjectOutputStream outputToClient = new ObjectOutputStream(
      socket.getOutputStream());

    clients.add(outputToClient);
    outputToClient.writeObject(arrayToString(secretWordArray));

    // Continuously serve the client
    while (true) {

      // some unnecessary things that server makes
    }
  }

}
}

当使用Object Stream的套接字时,这是一个经典的“陷阱”。 Object流格式有一个头,它由ObjectOutputStream的构造函数编写,并由ObjectInputStream的构造函数读取。 因此,您的构造函数调用阻止尝试从套接字读取标头(尚未写入,因为另一端同样被阻止)。

解决方案(用于连接的两端):

  1. 创建ObjectOutputStream
  2. flush() ObjectOutputStream
  3. 然后创建ObjectInputStream

这将确保将Object流标头写入套接字并发送到接收器,以便可以成功构造ObjectInputStream。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM