Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么在客户端类中创建ObjectInputStream时它会阻塞?(套接字编程)_Java_Sockets_Network Programming_Objectinputstream_Objectoutputstream - Fatal编程技术网

Java 为什么在客户端类中创建ObjectInputStream时它会阻塞?(套接字编程)

Java 为什么在客户端类中创建ObjectInputStream时它会阻塞?(套接字编程),java,sockets,network-programming,objectinputstream,objectoutputstream,Java,Sockets,Network Programming,Objectinputstream,Objectoutputstream,当我在服务器客户端程序中使用DataOutputStream/DataInputStream时,一切都很顺利,但在我决定使用ObjectInputStream/ObjectOutputStream之前,我在创建ObjectInputStream/ObjectOutputStream时遇到了一个问题。我和我的朋友看不出问题出在哪里。如果有人知道的话,那就太感谢了。这是我的“MyClient”和“MultiThreadServer”类 它正好出现在MyClient类中的“fromServer=new

当我在服务器客户端程序中使用DataOutputStream/DataInputStream时,一切都很顺利,但在我决定使用ObjectInputStream/ObjectOutputStream之前,我在创建ObjectInputStream/ObjectOutputStream时遇到了一个问题。我和我的朋友看不出问题出在哪里。如果有人知道的话,那就太感谢了。这是我的“MyClient”和“MultiThreadServer”类

它正好出现在MyClient类中的“fromServer=newObjectInputStream(s.getInputStream());”行

这是我的“MyClient”类:

下面是我的“MutliThreadServer”类:

公共类多线程服务器{
私密字串;
公共插座;
public ArrayList clients=new ArrayList();
服务器套接字服务器套接字;
公共静态void main(字符串[]args){
新的多线程服务器();
}
公共多线程服务器(){
试一试{
serverSocket=新的serverSocket(8080);
System.out.println(“多线程服务器在“+new Date()+”\n”)启动);
int clientNo=1;
while(true){
s=serverSocket.accept();
System.out.println(“客户端的启动线程”+clientNo+”在“+new Date()+”\n');
InetAddress InetAddress=s.getInetAddress();
System.out.println(“客户端”+clientNo+”的主机名是“+inetAddress.getHostName()+”\n”);
System.out.println(“客户端”+clientNo+”的IP地址是“+inetAddress.getHostAddress()+”\n”);
HandleAClient任务=新的HandleAClient;
新线程(任务).start();
clientNo++;
}
}
捕获(IOEX异常){
系统错误打印项次(ex);
}
}
类handleClient实现可运行{
专用插座;
公共手持客户端(插座){
this.socket=socket;
}
/**运行线程*/
公开募捐{
试一试{
ObjectInputStream inputFromClient=新ObjectInputStream(
socket.getInputStream());
ObjectOutputStream OutputClient=新的ObjectOutputStream(
getOutputStream());
clients.add(outputToClient);
outputToClient.writeObject(arrayToString(secretWordArray));
//持续为客户服务
while(true){
//服务器制造的一些不必要的东西
}
}
}
}
当使用对象流的over sockets时,这是一个经典的“陷阱”。对象流格式有一个头,由ObjectOutputStream的构造函数写入,由ObjectInputStream的构造函数读取。因此,您的构造函数调用正在阻止尝试从套接字读取头(尚未写入,因为另一端也被阻塞

解决方案(连接两端):

  • 在ObjectOutputStream中创建
  • flush()
    ObjectOutputStream
  • 然后创建ObjectInputStream

  • 这将确保将对象流头写入套接字并发送到接收器,以便成功构建ObjectInputStreams。

    我直截了当地按照您所说的做了。在客户端和服务器类中,我首先创建了ObjectOutputStream,然后创建了flush()就在我创建ObjectInputStream之后。这次它成功地完成了ObjectOutputStream和flush()的创建但是在创建ObjectInputStream时出现问题。:/@user2949556在这种情况下,对等方根本没有创建ObjectOutputStream。在创建ObjectOutputStream之前,这一过程不会继续。使用新的try with/as资源,是否仍有必要刷新对象输出流?如果同时创建它们呢?@Thufir-try/with功能如何实现ect任何内容?您是否阅读了开头部分,其中指出了您必须刷新输出流的原因?@Tareq如果无法连接到服务器,它将抛出异常,而不是在“new ObjectInputStream()”中阻塞。重复的
    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. 
    
    
        }
    
    }
    }
    
    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
        }
      }
    
    }
    }