当前位置: 首页 > 面试题库 >

ObjectInputStream(socket.getInputStream()); 不起作用

周正真
2023-03-14
问题内容

我正在编程一个类以与服务器进行通信,但是当它尝试在inputstream的帮助下构造ObjectInputStream时,程序将冻结。没有异常,程序仍在运行,但挂在试图构造ObjectInputstream的行中。

这是我的问题所在的方法的代码:

@Override
public void connect(String ip, int port) throws UnknownHostException, IOException {
    Socket socket = new Socket(ip, port);
    out = new ObjectOutputStream(socket.getOutputStream());
    InputStream is = socket.getInputStream();
    in = new ObjectInputStream(is);
}

这是整个类的代码:

package Client;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;


public class MessageStreamerImpl implements MessageStreamer {
    ObjectOutputStream out;
    ObjectInputStream in;

    public MessageStreamerImpl(String ip, int port) throws UnknownHostException, IOException{
        connect(ip, port);
    }

    public MessageStreamerImpl(){
    }

    @Override
    public void send(Object message) throws IOException {
        if(out == null) throw new IOException();
        out.writeObject(message);
        out.flush();
    }

    @Override
    public Object receive() throws IOException{
        try {
            return in.readObject();
        } catch (ClassNotFoundException e) {
            throw new IOException();
        }
    }

    @Override
    public void connect(String ip, int port) throws UnknownHostException, IOException {
        Socket socket = new Socket(ip, port);
        out = new ObjectOutputStream(socket.getOutputStream());
        InputStream is = socket.getInputStream();
        in = new ObjectInputStream(is);
    }

}

在查看Google时,我发现了这一点:http : //www.coderanch.com/t/232944/threads/java/Socket-
getInputStream-block
。但是我仍然不知道如何解决该问题,因为我的ObjectOutputStream构造函数在ObjectInputStream的构造函数之前。

这是我的服务器代码,也许会有所帮助;)

package Server;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;

public class Server {
    ArrayList<Socket> clients = new ArrayList<Socket>();

    public Server(int port){
        try {
            ServerSocket mySocket = new ServerSocket(port);
            waitForClients(mySocket);
        } catch (IOException e) {
            System.out.println("Unable to start.");
            e.printStackTrace();
        }
    }

    private void waitForClients(ServerSocket mySocket) {
        while(true){
            try {
                System.out.println("Ready to receive");
                Socket client = mySocket.accept();
                clients.add(client);
                System.out.println(client.getInetAddress().getHostAddress()+" connected to the Server");
                Thread t = new Thread(new ClientHandler(client));
                t.start();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    public void shareToAll(Object objectToSchare){
        for(Socket client:clients){
            ObjectOutputStream oos;
            try {
                oos = new ObjectOutputStream(client.getOutputStream());
                oos.writeObject(objectToSchare);
                oos.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    private class ClientHandler implements Runnable{
        Socket clientSocket;

        public ClientHandler(Socket clientSocket){
            this.clientSocket = clientSocket;
        }
        @Override
        public void run() {
            try {
                ObjectInputStream ois = new ObjectInputStream(clientSocket.getInputStream());
                while(true){
                    try {
                        ois.readObject();

                    } catch (ClassNotFoundException | IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }catch(SocketException e){
                System.out.println(clientSocket.getInetAddress().getHostAddress()+" disconnected from the Server");
                clients.remove(clientSocket);
            }catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

感谢您的帮助,我发现了问题。它是在服务器类上,看起来像这样:

package Server;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;

public class Server {
    ArrayList<ObjectOutputStream> clientstreams = new ArrayList<ObjectOutputStream>();

    public Server(int port){
        try {
            ServerSocket mySocket = new ServerSocket(port);
            waitForClients(mySocket);
        } catch (IOException e) {
            System.out.println("Unable to start.");
            e.printStackTrace();
        }
    }

    private void waitForClients(ServerSocket mySocket) {
        while(true){
            try {
                System.out.println("Ready to receive");
                Socket client = mySocket.accept();
                clientstreams.add(new ObjectOutputStream(client.getOutputStream()));
                System.out.println(client.getInetAddress().getHostAddress()+" connected to the Server");
                Thread t = new Thread(new ClientHandler(client));
                t.start();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    public void shareToAll(Object objectToSchare){
        for(ObjectOutputStream stream:clientstreams){
            try {
                stream.writeObject(objectToSchare);
                stream.flush();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    private class ClientHandler implements Runnable{
        Socket clientSocket;

        public ClientHandler(Socket clientSocket){
            this.clientSocket = clientSocket;
        }
        @Override
        public void run() {
            try {
                ObjectInputStream ois = new ObjectInputStream(clientSocket.getInputStream());
                while(true){
                    try {
                        ois.readObject();

                    } catch (ClassNotFoundException | IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }catch(SocketException e){
                System.out.println(clientSocket.getInetAddress().getHostAddress()+" disconnected from the Server");
                clientstreams.remove(clientSocket);
            }catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }   
}

您在方法waitForClients()上看到的更改最多,但是我也更改了ArrayList和shareToAll方法的概念。


问题答案:

ObjectInputStream构造函数从给定的InputStream读取数据。为了使它起作用, 必须
在构造后立即刷新ObjectOutputStream(以写入初始标头),然后再尝试打开ObjectInputStream。同样,如果您希望每个连接发送多个对象,则必须打开一次ObjectOutputStream并将其用于套接字的生命周期(例如您的shareToAll方法)。



 类似资料:
  • 问题内容: 伙计们,我现在感觉真的很愚蠢。…基本上我是通过本地计算机上的TCP连接的…并且当我尝试在客户端创建In / out流时,不会通过创建对象输入流。是什么赋予了?这在打印2之后停止…没有异常或任何事情…这不是我第一次使用此类,这是我感到困惑的部分原因。 问题答案: 根据ObjectInputStream 的规范: 该构造函数将阻塞,直到相应的ObjectOutputStream写入并刷新了

  • 问题内容: 我有一些课程:客户端,服务器和后台正在使用Player类。我真的不明白为什么带/的Client类无法正常工作。 我在做什么不好?我的错在哪里 现在客户端类: 它不会将Object发送到Server类,但也不会对错误进行任何说明。 服务器类: 问题答案: 您正在循环关闭流。关闭流或任何资源后,您将无法使用它。

  • 因此,我在一个控制器中有一个非常简单的代码片段,在这个代码片段中,我使用从外部文件中获取数据,它工作得很好!但是当我使用时,我会在控制台中得到一个

  • 问题内容: 正则表达式似乎还可以,因为第一行将子字符串正确替换为“ helloworld”,但是后者却不匹配,因为我看不到“ whynothelloworld?”。在控制台上 问题答案: 期望 整个 字符串匹配,而不仅仅是子字符串。 使用正则表达式匹配器对象的方法代替:

  • 问题内容: 我的 活动无法正常进行。 以下是我一一尝试过的代码段,但无济于事: 使用方法实施 设定方法 使用方法 这是我完整的MainActivity.java文件: 问题答案: 我遇到了同样的问题,我发现Android非常注重布局XML。我将NavigationView作为DrawerLayout的第一个孩子,但是出于某些愚蠢的原因,它必须是最后一个孩子。因此,您的布局必须具有以下顺序的元素:

  • 问题内容: 在什么情况下,java的System.out.println无法产生任何输出。我在方法内部调用了它,有时在调用该方法时得到了println,而有时却没有。 更新:我还在println之后使用System.out.flush()。 更新:感谢您的调试帮助。原来,阻止调用打开了一个对话框,使输出看起来与正常顺序大相径庭。我以为我要打印消息的方法是在对话框关闭时被调用的,但是该方法本身就是在