/*
  
  Server.java

  Simple socket-based client server application. The server echoes
  back what the client sends which is what the user types in.

  Usage: java Server <port_number=8072>
  Terminate server with Ctrl-C 

  This file implements the server part

  (P)2000 Dana & Laurentiu Cristofor

*/

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

public class Server 
{
  private static LinkedList clients = new LinkedList();

  public static void main(String[] args) 
    throws IOException 
  {
    int port = 8072;

    if (args.length > 0)
      port = Integer.parseInt(args[0]);
      
    ServerSocket listener = new ServerSocket(port);
    System.out.println("The Server is running on port " + port);

    Socket client;
    ServerChild child;

    while (true) 
      {
	// get a connection request
	client = listener.accept();
	// create a new thread to deal with this client
	child = new ServerChild(client);
	child.start();
	// keep track of threads in a list
	clients.add(child);
	System.out.println("New client from " + listener.getInetAddress() 
			   + " on client's port " + client.getPort());
      }
  }

  // for removing a server thread from the list
  static synchronized void remove(ServerChild child) 
  {
    for (ListIterator iterator = clients.listIterator(0); iterator.hasNext();) 
      if (((ServerChild)iterator.next()).equals(child)) 
	{
	  iterator.remove();
	  break;
	}
  }    
}

class ServerChild extends Thread
{
  private Socket clientSocket;
  
  public ServerChild(Socket s)
  {
    clientSocket = s;
  }

  public Socket getClientSocket()
  {
    return clientSocket;
  }

  public void run() 
  {
    try 
      {
	ObjectInputStream in = new ObjectInputStream(clientSocket.getInputStream());
	ObjectOutputStream out = new ObjectOutputStream(clientSocket.getOutputStream());

	// send greeting to client
	out.writeObject("*** Welcome to the Server ***\nType BYE to end\nWhat is your name? ");
	// read name of client
	String name = (String)in.readObject();
	// print some info
	System.out.println(name + " has connected to the server.");
	
	while (true) 
	  {
	    // read client message
	    String s = (String)in.readObject();
	    // echo it back
	    out.writeObject(s);
	    // check if client wants to disconnect
	    if (s.equals("BYE")) 
	      {
		System.out.println(name + " has left the discussion.");
		break;
	      }
	    // print some info
	    System.out.println(name + " says: " + s);
	  }
	// remove this thread from the list of threads
	Server.remove(this);
	clientSocket.close();
      } 
    catch (Exception e) 
      {
	System.out.println("Server error: " + e);
      }
  }
}
