package object_ex;
 
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.BindException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;
 
public class Chat_Server {
  ServerSocket server=null;
  //ObjectInputStream input=null;
  
  boolean isStart=false;//服務端是否啟動
  boolean isConnect=false;//客戶端是否連接上
  object_data data = new object_data();
  
  ArrayList<Client_Thread> clients = new ArrayList<Client_Thread>();
  public static void main(String[] args) {
    new Chat_Server().startServer();
  }
 
  private void startServer(){
    System.out.println("server is running");
    try{
      server=new ServerSocket(8888);
      isStart=true;
    }catch(BindException e){
      System.out.println("port has been used");
      System.exit(0);
    }catch(IOException e){
      e.printStackTrace();
      System.exit(0);
    }
    try {
      while(isStart){
        Socket client=server.accept();
        //client成功連接後，為該client創立一個獨立的thread來接收消息
        Client_Thread client_thread=
            new Client_Thread(client);
        new Thread(client_thread).start();//啟動thread
        clients.add(client_thread);//加入thread
      }
    }catch(Exception e){
      e.printStackTrace();
    }
    finally{
      try {
        server.close();
      } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
    }
  }
 
  /*
   * 每當一個client連接到時，都會創立一個如下的thread
   */
  class Client_Thread implements Runnable{
    
    //在此內保留socket、inputStream
    private Socket Sock=null;
    private ObjectInputStream in=null;
    private ObjectOutputStream output=null;
    private boolean isConnect=false;
    Client_Thread(Socket s){
      this.Sock=s;
      try {
        in=new ObjectInputStream(s.getInputStream());
        output=new ObjectOutputStream(s.getOutputStream());
        isConnect=true;
      } catch (IOException e) {
        // TODO Auto-generated catch block
        System.out.println("Client_Thread");
        e.printStackTrace();
      }
    }
    
    public void send(String str){
      try {
        data.setchat(str);
        output.writeObject(data);
        output.flush();
      } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
    }
    
    public void run() {
      System.out.println("server is watting(伺服器等待中)");
        String str = null;
        try {
          while(isConnect){
            data = (object_data)in.readObject();
            str = data.getchat();
            //str = (String)in.readObject();
            System.out.println(str);
            
            for(int i=0;i<clients.size();i++){
              Client_Thread c=clients.get(i);
              c.send(str);
            }
          }  
        } catch (SocketException e) {
          System.out.println("client has been closed");
        } catch (Exception e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        }
        finally{
          try {
            if(in!=null) in.close();
            if(output!=null) output.close();
            Sock.close();
            } catch (IOException e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
            }
        }
    }
  }
}