ObjectInputStream(socket.getInputStream()); ne fonctionne pas
Je suis à la programmation d'une classe de communiquer à un serveur, mais quand il essaie de construire la ObjectInputStream avec l'aide de l'inputstream le programme de congélation. Theres ne fait pas Exception et le programme est encore en cours d'exécution, mais la pendaison dans la ligne où il essaie de construire le ObjectInputstream.
Heres le code de la méthode où mon problème est situé:
@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);
}
et c'est le code pour l'ensemble de la classe:
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);
}
}
En cherchant sur Google j'ai trouvé ceci: http://www.coderanch.com/t/232944/threads/java/Socket-getInputStream-block. Mais je ne sais toujours pas comment résoudre le problème, parce que mon ObjectOutputStream constructeur est avant celui de la ObjectInputStream.
Voici mon code serveur, peut-être que ça va aider 😉
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();
}
}
}
}
Merci pour votre aide, j'ai trouvé la faille. C'est à la classe serveur qui doit ressembler à ceci:
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();
}
}
}
}
La plupart des changements que vous voyez à la méthode waitForClients() mais j'ai changé aussi le concept de mon ArrayList et la shareToAll méthode.
OriginalL'auteur Big_Foot1989 | 2011-12-04
Vous devez vous connecter pour publier un commentaire.
la ObjectInputStream constructeur lit les données à partir de la donnée InputStream. pour que cela fonctionne, vous doit rincer le ObjectOutputStream immédiatement après la construction (pour écrire l'en-tête initial) avant d'essayer d'ouvrir la ObjectInputStream. aussi, si vous souhaitez envoyer plus d'un objet par la connexion, vous devez ouvrir le ObjectOutputStream une fois et l'utiliser pour la durée de vie du support (par exemple, votre
shareToAll
méthode).J'ai édité la question, parce que je ne suis pas autorisé à répondre à mes propres questions encore.
vous avez encore ne devrait pas être la redéfinition de l'entrée et les flux de sortie à chaque fois. Ils devraient être global à l'intérieur de la
ClientHandler
classe.Qu'ils sont. Ou presque... mais je construisent-ils une seule fois maintenant. Le Outputstreams sont maintenant représentés à ma liste de tableaux et l'Inputstream est défié une fois avant la boucle while dans mon ClientHandler 😉
OriginalL'auteur jtahlborn