2014-10-21 4 views
0

그래서 저는 자바 서버와 클라이언트를 만들고 있습니다.Java ObjectInputStream (소켓 소켓)이 전체 응용 프로그램을 다시 시작합니까?

현재 내 클라이언트는 서버에 연결하고 클라이언트 및 서버 쪽 모두에 대해 개체 입력 및 출력 스트림을 만듭니다.

즉시 해당 서버의 ObjectInputStream (소켓 소켓)을 통해 데이터를 받으면 전체 프로그램이 다시 시작됩니다.

오류나 예외 또는 다른 언급이 없습니다. 클라이언트가 말합니다 : "서버 연결을 닫았습니다 : java.net.SocketException : socket closed"< - 그래서 서버는 소켓과 관련된 모든 것을 닫습니다.

은 여기 내 서버와 클라이언트의 (+ 보너스 질문 : 서버 및 클라이언트하지만, 그 객체가 만들어지는 방식이 동일한 다른 명명 된 객체 내가 보내고 소켓을 통해 사람들을 읽을 수있는 경우?)

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

클라이언트는 말한다는 : "서버 연결을 닫았습니다 : java.net.SocketException의 : 소켓은 폐쇄"

그게 입니다. 메시지이며 올바르지 않습니다. 일 때마다IOException은 서버가 연결을 종료했음을 의미합니다. 이것은 확실하지 않습니다. 두 가지 예외는 실제로는 EOFException이고 대개는 IOException: connection reset입니다.

이 특정의 예외는 SocketException: socket closed이며, 그 의미는 당신클라이언트가 연결을 종료 한 다음 계속 사용한다는 것입니다. 예를 들어, 초기 로그인이 실패하면 연결을 끊지 만 리스너 스레드는 계속 실행 중이며 읽기를 시도합니다.

잘못된 가정을하여 사용자를 오도하지 마십시오. 특히 오류 메시지에 포함시키지 마십시오.

NB :

  1. 는 만들 필요가 ObjectInputStream.

  2. 리스너 스레드가 EOFException를 캐치 캐치 할 때 루프의 탈옥 할 필요가 ObjectOutputStream 전에.