ObjectInputStream的(socket.getInputStream());不起作用 [英] ObjectInputStream(socket.getInputStream()); does not work

查看:88
本文介绍了ObjectInputStream的(socket.getInputStream());不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我正在编写一个类来与服务器进行通信,但是当它尝试在输入流的帮助下构造ObjectInputStream时程序正在冻结。 Theres没有Exception,程序仍然在运行,但是在它试图构造ObjectInputstream的行中挂起。



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

  @Override 
public void connect(String ip,int port)抛出UnknownHostException,IOException {
Socket socket = new Socket(ip,port);
out = new ObjectOutputStream(socket.getOutputStream());
InputStream = 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;


公共类MessageStreamerImpl实现MessageStreamer {
ObjectOutputStream out;
ObjectInputStream in;

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

public MessageStreamerImpl(){
}

@Override
public void send(Object message)throws IOException {
if(out == null)抛出新的IOException();
out.writeObject(message);
out.flush();
}

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

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

}

在看Google时我发现了这个: http://www.coderanch.com/t/232944/线程/ JAVA /编程的getInputStream块。但是我仍然不知道如何解决这个问题,因为我的ObjectOutputStream构造函数在ObjectInputStream的构造函数之前。



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

 包服务器; 

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(无法启动。);
e.printStackTrace();
}
}

private void waitForClients(ServerSocket mySocket){
while(true){
try {
System.out.println (准备接收);
Socket client = mySocket.accept();
clients.add(客户端);
System.out.println(client.getInetAddress()。getHostAddress()+连接到服务器);
线程t =新线程(新ClientHandler(客户端));
t.start();
} catch(IOException e){
// TODO自动生成的catch块
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自动生成的catch块
e.printStackTrace();
}
}
}

私有类ClientHandler实现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自动生成的catch块
e.printStackTrace();
}
}
} catch(SocketException e){
System.out.println(clientSocket.getInetAddress()。getHostAddress()+与服务器断开连接);
clients.remove(clientSocket);
} catch(IOException e){
// TODO自动生成的catch块
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(无法启动。);
e.printStackTrace();
}
}

private void waitForClients(ServerSocket mySocket){
while(true){
try {
System.out.println (准备接收);
Socket client = mySocket.accept();
clientstreams.add(new ObjectOutputStream(client.getOutputStream()));
System.out.println(client.getInetAddress()。getHostAddress()+连接到服务器);
线程t =新线程(新ClientHandler(客户端));
t.start();
} catch(IOException e){
// TODO自动生成的catch块
e.printStackTrace();
}
}
}

public void shareToAll(Object objectToSchare){
for(ObjectOutputStream stream:clientstreams){
try {
stream.writeObject(objectToSchare);
stream.flush();
} catch(IOException e){
// TODO自动生成的catch块
e.printStackTrace();
}
}
}

私有类ClientHandler实现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自动生成的catch块
e.printStackTrace();
}
}
} catch(SocketException e){
System.out.println(clientSocket.getInetAddress()。getHostAddress()+与服务器断开连接);
clientstreams.remove(clientSocket);
} catch(IOException e){
// TODO自动生成的catch块
e.printStackTrace();
}
}
}
}

您在方法waitForClients()中看到的大多数更改,但我也改变了我的ArrayList和shareToAll方法的概念。

解决方案

ObjectInputStream构造函数从给定的InputStream中读取数据。为了使其正常工作,在尝试打开ObjectInputStream之前,必须在构造之后立即刷新ObjectOutputStream(以编写初始头)。另外,如果要为每个连接发送多个对象,则必须打开ObjectOutputStream一次并将其用于套接字的生命周期(例如, shareToAll 方法)。 / p>


I'm programming a class to communicate to a server but when it tries to construct the ObjectInputStream with the help of the inputstream the program is freezing. Theres is no Exception and the program is still running but hanging in the line where it tries to construct the ObjectInputstream.

Heres the code of the method where my problem is located:

@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);
}

and this is the code for the whole class:

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);
    }

}

While looking at Google I found this: http://www.coderanch.com/t/232944/threads/java/Socket-getInputStream-block. But I still don't know how to solve the problem, because my ObjectOutputStream constructor is before the one for the ObjectInputStream.

Here is my server code, maybe it will help ;)

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();
            }
        }
    }
}

Thanks for your help I found the fault. It was at the server class which has to look like this:

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();
            }
        }
    }   
}

The most changes you see at the method waitForClients() but I changed, too the concept of my ArrayList and the shareToAll method.

解决方案

the ObjectInputStream constructor reads data from the given InputStream. in order for this to work, you must flush the ObjectOutputStream immediately after constuction (to write the initial header) before you attempt to open the ObjectInputStream. also, if you want to send more than one object per connection, you must open the ObjectOutputStream once and use it for the lifetime of the socket (e.g. your shareToAll method).

这篇关于ObjectInputStream的(socket.getInputStream());不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆