当前位置: 首页 > 知识库问答 >
问题:

为什么在Client类中创建ObjectInputStream时会发生堆积?(套接字编程)

尹辰沛
2023-03-14

当我在服务器-客户机程序中使用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
    }
  }

}
}

共有1个答案

云飞翮
2023-03-14

在套接字上使用对象流时,这是一个典型的“gotcha”。对象流格式有一个头,它由ObjectOutputStream的构造函数写入,并由ObjectInputStream的构造函数读取。因此,您的构造函数调用阻止了从套接字读取头的尝试(因为另一端也被阻止,所以还没有写入头)。

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

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

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

 类似资料:
  • 假设通过网络在两个套接字之间建立tcp连接。一个是服务器端,另一个是客户端。 谢谢

  • 有ManyToOne链接的表。每个学生被分配一个方向从教育方向。当我创建学生时,所选方向被重新创建。为什么在创建学生时创建方向? 学生: 教育方向: 学生道:

  • 当我用main方法为类创建对象时会发生什么?我能在main方法中使用这些实例变量吗,因为它们在同一个类中?

  • 问题内容: 我的老师给我一个问题: “用Java创建对象时会发生什么”。 据我所知,创建对象时会发生内存分配,变量初始化和构造函数方法调用。 但是我的老师说我几乎是对的。后面的两件事是正确的,除了内存堆。相反,他说发生了内存分配。我认为对象存储在堆中,所以我的老师错了。你这样认为吗? 问题答案: 与往常一样,找到针对此类问题的解决方案的最佳位置是Java语言规范。 具体来说,从创建新实例的部分可以

  • 我正在开发一个使用TCP套接字的客户端(Java)/服务器(C++)应用程序。我使用的协议由2个字节开头的消息组成,这些字节定义了消息内容的类型。所以基本上,接收线程在循环中等待接收数据。但我希望使用套接字的超时通知其他主机发送数据的时间过长。

  • 当我进行套接字编程时,我无法清楚地理解。 我的理解是 如果我使用此选项打开套接字,表示我可以在header之前创建自己的header,但最终数据以 /code>协议的格式发送。我的理解是正确的。如果错了,可以一些解释。 谢谢