简体   繁体   English

Java ObjectInputStream(Socket socket)重新启动整个应用程序?

[英]Java ObjectInputStream(Socket socket) restarts the whole application?

So I'm making a java Server and Client. 所以我正在制作一个Java服务器和客户端。

Currently my Client connects to the server and creates Object input and Output streams for both client and server side. 当前,我的客户端连接到服务器,并为客户端和服务器端创建对象输入和输出流。

Immediately when I try to receive data over that ObjectInputStream(Socket socket) of Server it restarts the whole program. 当我尝试通过Server的ObjectInputStream(Socket socket)接收数据时,它将立即重新启动整个程序。

It doesen't even mention about any errors or exceptions or others? 它甚至没有提到任何错误或异常或其他? Client says: "Server has closed the connection: java.net.SocketException: socket closed" <- so Server also closes the socket and everything related to it. 客户端说:“服务器已关闭连接:java.net.SocketException:套接字已关闭” <-因此服务器也将关闭套接字及其相关的所有内容。

Here's my Server and Client (+ Bonus question: If there are different named objects in Server and Client but the way those objects are made are the same, can I send and read those over socket?) 这是我的服务器和客户端(+奖励问题:如果服务器和客户端中有不同的命名对象,但是这些对象的制造方式相同,我可以通过套接字发送和读取这些对象吗?)

package com.server;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.ServerSocket;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

import com.gui.Screen;
import com.gui.TextArea;

public class Server implements Runnable{
//Every connection got their own unique id
private static int uniqueId;
//List all the clients
private static ArrayList<ClientThread> al;
private static boolean running = false;
@SuppressWarnings("unused")
private SimpleDateFormat sdf;
ServerSocket serverSocket;

public Server(int port) {
    sdf = new SimpleDateFormat("HH:mm:ss");
    al = new ArrayList<ClientThread>();
}

public void run() {
    running = true;
    try {
        serverSocket = new ServerSocket(Screen.portnumber);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    try {
        //Server socket
        TextArea.AddLine("Server is running and waiting for Clients to connect.");
        while(running){
            Socket socket = serverSocket.accept();
            ClientThread t = new ClientThread(socket);
            al.add(t); //saving new client to our arraylist.
            t.run();
            if(!running){ //this will make server running stop.
                TextArea.AddLine("Closing the server..");
                break;
            }
        }
        for(int i = 0; i< al.size(); i++){//We forget about all the clients.
            //Maybe also save all the data here?
            ClientThread tc = al.get(i);
            try{
            tc.sInput.close();
            tc.sOutput.close();
            tc.socket.close();
            }
            catch(IOException ioE){

            }
        }
        serverSocket.close();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

public static void close() {
    running = false;
    try {
        new Socket("localhost", Screen.portnumber);
    } catch (Exception e) { TextArea.AddLine("Can't disconnect.."); }
}

    synchronized void remove(int id) {
        // scan the array list until we find the Id
        for(int i = 0; i < al.size(); ++i) {
            ClientThread ct = al.get(i);
            // found it
            if(ct.id == id) {
                al.remove(i);
                return;
            }
        }
    }

public static boolean isRunning(){
    return running;
}

    class ClientThread extends Thread {
        //The socket where to listen/talk
        Socket socket;
        ObjectInputStream sInput;
        ObjectOutputStream sOutput;
        //my unique id (easier for deconnection)
        int id;
        //Objects that we will be receiving
        Incomingdata datain;
        //the date we connect
        String date;
        Player player;

        //Constructor
        ClientThread(Socket socket){
            id = uniqueId++;
            this.socket = socket;
            try{
                sOutput = new ObjectOutputStream(socket.getOutputStream());
                sInput = new ObjectInputStream(socket.getInputStream());
            } catch (Exception e){
                System.out.println("Couldn't create Input/Output streams");
            }
            date = new Date().toString();
        }

        // what will run forever
        public void run() {
            // to loop until LOGOUT
            boolean Connected = true;
            while(Connected) {
                // Read incoming data
                try {
                    //Everything works until that
                    datain = (Incomingdata) sInput.readObject();
                    //at this point the program restarts?
                }
                catch (IOException e) {
                    TextArea.AddLine(Incomingdata.getUsername(datain) + " Exception reading Streams: " + e);
                    break;              
                }
                catch(ClassNotFoundException e2) {
                    break;
                }
                if(datain != null){
                    // Switch on the type of message receive
                    switch(Incomingdata.getAction(datain).getType()) {

                    case 0://Log off
                        TextArea.AddLine(Player.getUsername(player) + " logged off.");
                        Connected = false;
                        break;
                    case 1://Talk
                        TextArea.AddLine(Incomingdata.getUsername(datain) + ": " +Incomingdata.getAction(datain).getString());
                        break;
                    case 2://Move
                        Player.move(player);
                    }
                }
            }
            // remove myself from the arrayList containing the list of the
            // connected Clients
            remove(id);
            close();
        }

        // try to close everything
        private void close() {
            // try to close the connection
            try {
                if(sOutput != null) sOutput.close();
            }
            catch(Exception e) {}
            try {
                if(sInput != null) sInput.close();
            }
            catch(Exception e) {};
            try {
                if(socket != null) socket.close();
            }
            catch (Exception e) {}
        }
    }
}

and Client: 和客户:

package com.connection;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;

public class Client {

// for I/O
private ObjectInputStream sInput;       // to read from the socket
private static ObjectOutputStream sOutput;      // to write on the socket
private Socket socket;
private Outgoingdata lastdata;
private Outgoingdata currentdata;
static Client client;
public static boolean connected = false;
public static Player player;

String server;
int port;

Client(String server, int port) {
    this.server = server;
    this.port = port;
}

/*
 * When something goes wrong
 * Close the Input/Output streams and disconnect not much to do in the catch clause
 */
private void disconnect() {
    try { 
        if(sInput != null) sInput.close();
    }
    catch(Exception e) {} // not much else I can do
    try {
        if(sOutput != null) sOutput.close();
    }
    catch(Exception e) {} // not much else I can do
    try{
        if(socket != null) socket.close();
    }
    catch(Exception e) {} // not much else I can do
}

public boolean start() {
    // try to connect to the server
    try {
        socket = new Socket(server, port);
    } 
    // if it failed not much I can so
    catch(Exception ec) {
        System.out.println("Error connectiong to server:" + ec);
        return false;
    }

    System.out.println("Connection accepted " + socket.getInetAddress() + ":" + socket.getPort());

    /* Creating both Data Stream */
    try
    {
        sInput  = new ObjectInputStream(socket.getInputStream());
        sOutput = new ObjectOutputStream(socket.getOutputStream());
    }
    catch (IOException eIO) {
        System.out.println("Exception creating new Input/output Streams: " + eIO);
        return false;
    }

    // creates the Thread to listen from the server 
    new ListenFromServer().start();
    // Send our username to the server this is the only message that we
    // will send as a String. All other messages will be ChatMessage objects
    try
    {
        sOutput.writeObject(new Incomingdata("minisurma", "kaikim", null));
    }
    catch (IOException eIO) {
        System.out.println("Exception doing login : " + eIO);
        disconnect();
        return false;
    }
    // success we inform the caller that it worked
    return true;
}

public static void Connect() {
    // default values
    int portNumber = 1500;
    String serverAddress = "localhost";

    // create the Client object
    client = new Client(serverAddress, portNumber);
    // test if we can start the connection to the Server
    // if it failed nothing we can do
    if(!client.start())
        return;
    connected = true;
}

public static void Disconnect() {
    connected = false;
    client.disconnect();
}

class ListenFromServer extends Thread {

    public void run() {
        while(true) {
            try {
                Outgoingdata data = (Outgoingdata) sInput.readObject();
                System.out.println("data");
            }
            catch(IOException e) {
                System.out.println("Server has closed the connection: " + e);
            }
            // can't happen with a String object but need the catch anyhow
            catch(ClassNotFoundException e2) {
            }
        }
    }
}

public static void send(Incomingdata incomingdata) {
    try {
        sOutput.writeObject(incomingdata);
    }
    catch(IOException e) {
        System.out.println("Exception writing to server: " + e);
    }
}
}

Client says: "Server has closed the connection: java.net.SocketException: socket closed" 客户端说:“服务器已关闭连接:java.net.SocketException:套接字已关闭”

That's your message, and it isn't correct. 那是你的信息,这是不正确的。 You're assuming that every IOException means that the server closed the connection. 您假设每个 IOException意味着服务器关闭了连接。 This is certainly not so. 当然不是这样。 The only two exceptions that really mean that are EOFException and, usually, IOException: connection reset . 实际上只有两个例外是EOFException和通常是IOException: connection reset

This particular exception is a SocketException: socket closed , and its meaning is that you , the client , closed the connection and then continued to use it. 这个特定的异常是SocketException: socket closed ,其含义是客户端 )关闭了连接,然后继续使用它。 For example, if your initial login fails, you disconnect, but your listener thread is still running, trying to read. 例如,如果您的初始登录失败,则断开连接,但侦听器线程仍在运行,尝试读取。

Don't mislead yourself by making false assumptions, and especially don't build them into your error messages. 不要通过做出错误的假设来误导自己,尤其是不要将其内置到错误消息中。

NB: 注意:

  1. You need to create the ObjectOutputStream before the ObjectInputStream. 您需要在ObjectInputStream. 之前创建ObjectOutputStream ObjectInputStream.

  2. Your listener thread needs to catch EOFException and break out of the loop when it is caught. 您的侦听器线程需要捕获EOFException并在捕获时脱离循环。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM