一个客户端断开连接后服务器关闭(JAVA)

时间:2015-01-23 14:32:53

标签: java server

我的服务器在一个客户端断开连接后关闭,我只能写一个消息然后崩溃。我想知道为什么,因为我只在它键入" EXIT SERVER"时关闭客户端套接字。这是它抛出的例外:

      java.io.EOFException

这是我的代码:

 import java.net.*;
  import java.io.*;

  public class ServerPeer extends Thread {

Socket _socket;
String username;

public ServerPeer(Socket _socket) {
    this._socket = _socket;
}

public void sendMessage(String _username, String _message) throws IOException {
    ObjectOutputStream _obj = new ObjectOutputStream(
            _socket.getOutputStream());
    _obj.writeObject(new Message(_username, _message));
    _obj.flush();

  }

public synchronized void run() {
    try {
        ObjectInputStream _ois = new ObjectInputStream(_socket.getInputStream());
        Message _message;
        while (_socket.isConnected()) {

            _message = (Message) _ois.readObject();

            String divide = _message.getAll().substring(0, _message.getAll().indexOf(":"));
            username = divide;
            Server.listofusers.add(username);
            for (ServerPeer sp : Server.listofpeers) {
                if (_message.getAll().contains("EXIT SERVER")) {
                    Server.listofpeers.remove(sp);

                    _socket.close();
                }
                if (_message instanceof PrivateMessage) {
                    PrivateMessage privm = (PrivateMessage) _message;

                    for (ServerPeer sp2 : Server.listofpeers) {
                        if (sp2.username.equals(privm.getReceiver())) {
                            sp2.sendMessage(divide, privm.getAll());
                            String priv = privm.getAll().replaceAll("/w", "");
                            System.out.println(priv);
                            break;
                        }
                    }

                } else {
                    sp.sendMessage(divide, _message.getAll());

                    System.out.println(_message.getAll());
                }

            }

            _ois = new ObjectInputStream(_socket.getInputStream());

        }

    } catch (IOException e) {
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
      }
   }
  }

服务器类:

import java.io.*;
import java.net.*;
import java.util.*;

 public class Server {

static ServerConfig _svconfig = new ServerConfig();
public static ArrayList<ServerPeer> listofpeers = new ArrayList<ServerPeer>();

public static ArrayList<String> listofusers = new ArrayList<String>();
public static int i = 0;
// final static int _mysocket;

public static void main(String[] args) {
    try {
        final int _mysocket = _svconfig.getPORTNumber();
        System.out.println("Wainting for clients.....");
        ServerSocket _serversocket = new ServerSocket(_mysocket, _svconfig.getCLIENTSNumber());
        while (listofpeers.size() <= _svconfig.getCLIENTSNumber()) {
            Socket _clientsocket = _serversocket.accept();
            ServerPeer _serverpeer = new ServerPeer(_clientsocket);
            _serverpeer.start();
            listofpeers.add(_serverpeer);

        }
        _serversocket.close();
    } catch (MissingKeyException e) {
        e.printStackTrace();
    } catch (UnknownKeyException e) {
        e.printStackTrace();
    } catch (InvalidFormatException e) {
        e.printStackTrace();
    } catch (ConnectException e) {
        e.printStackTrace();
    } catch (BindException e) {
        e.printStackTrace();
    } catch (UnknownHostException e) {
        e.printStackTrace();
    } catch (IllegalArgumentException e) {
        e.printStackTrace();
    } catch (SecurityException e) {
        e.printStackTrace();
    } catch (SocketException e) {
        System.out.println("You have been disconnected");
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

}

}

编辑:

断开连接的客户端控制台中抛出异常:

 java.io.EOFException
at java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2328)
at java.io.ObjectInputStream$BlockDataInputStream.readShort(ObjectInputStream.java:2797)
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:802)
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:299)
at ClientPeer.serverEcho(ClientPeer.java:35)
at ClientPeer.run(ClientPeer.java:44)
   BUILD STOPPED (total time: 1 minute 26 seconds)

2 个答案:

答案 0 :(得分:0)

据我所知,我猜你的代码不正确,但没有更多代码就很难分辨。

乍一看,如果有太多人连接到您的服务器,您只需关闭整个服务器而不仅仅是那些连接。

while (listofpeers.size() <= _svconfig.getCLIENTSNumber()) {
   Socket _clientsocket = _serversocket.accept();
   ServerPeer _serverpeer = new ServerPeer(_clientsocket);
   _serverpeer.start();
   listofpeers.add(_serverpeer);
}
_serversocket.close();

更好的方法是类似以下内容。如果有太多用户尝试连接,只需关闭用户连接。

ServerSocket _serversocket = new ServerSocket(_mysocket, _svconfig.getCLIENTSNumber());
boolean alive = true;
while (alive) {

    try {
        //Keep accepting connection request
        Socket clientRequest = _serversocket.accept();

        //Check if too many user are connected
        if (listofpeers.size() <= _svconfig.getCLIENTSNumber()) {
            ServerPeer _serverpeer = new ServerPeer(_clientsocket);
            _serverpeer.start();
            listofpeers.add(_serverpeer);
        }else{
            //Reject connection if too many connected
            clientRequest.close();
        }
    } catch (Throwable t) {
        t.printStackTrace();
    }
}
//When server dead close it down
_serversocket.close();

希望这会有所帮助。

答案 1 :(得分:0)

您的代码必须在客户端线程终止后退出,创建一个具有启动客户端线程的服务器接受方法的线程,如下所示,

/**
  */
  private class ServerListener extends Thread 
  {
    /**
    */
    public void run() 
    {
      try 
      {
         Socket clientSocket = socket.accept();
         System.out.println("client connected => "+clientSocket.getInetAddress().getHostAddress());
         ServerListener th = new ServerListener();
         th.start();

         ClientThread cth = new ClientThread(clientSocket);
         cth.start();
         clients.add(cth);

         return;
      }
      catch (Exception e)
      {
        e.printStackTrace();
        //Main.getInsatance().println(e);
        //Main.getInstance().println("socket disconnected => "+clientSocket.getInetAddress().getHostAddress());
      }
    }
  }