Java ObjectInputStream(套接字套接字)重启整个应用程序?

时间:2014-10-21 13:35:19

标签: java sockets connection objectinputstream

所以我正在制作一个java服务器和客户端。

目前,我的客户端连接到服务器,并为客户端和服务器端创建对象输入和输出流。

当我尝试通过Server的ObjectInputStream(套接字套接字)接收数据时,它立即重启整个程序。

它甚至没有提到任何错误或异常或其他错误?客户端说:"服务器已关闭连接:java.net.SocketException:socket closed" < - so服务器还会关闭套接字以及与之相关的所有内容。

这是我的服务器和客户端(+红利问题:如果服务器和客户端中有不同的命名对象,但这些对象的制作方式是相同的,我可以通过套接字发送和读取它们吗?)

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

和客户:

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

1 个答案:

答案 0 :(得分:1)

  

客户端说:&#34;服务器已关闭连接:java.net.SocketException:socket closed&#34;

你的消息,并不正确。您假设每个 IOException表示服务器已关闭连接。当然不是这样。真正意味着的唯一两个例外是EOFException,通常是IOException: connection reset

此特殊异常是SocketException: socket closed,其含义是客户端,关闭连接然后继续使用它。例如,如果您的初始登录失败,则断开连接,但您的侦听器线程仍在运行,尝试阅读。

不要通过做出错误的假设来误导自己,特别是不要将它们构建到错误信息中。

NB:

  1. 您必须先创建ObjectOutputStream ObjectInputStream.

  2. 您的侦听器线程需要捕获EOFException并在捕获时跳出循环。