Ho risolto facendo in modo che quando chiudo il frame il Socket e il ServerSocket vengano chiusi col metodo close() Anche se non capisco perchè non lo faccia automaticamente il dispose().

codice:
import java.io.EOFException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowListener;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

public class Server extends JFrame
{
	private JTextField enterField;
	private JTextArea displayArea;
	private ObjectOutputStream output;
	private ObjectInputStream input;
	private ServerSocket server;
	private Socket connection;
	private int counter = 1;
	private boolean closingFlag = false;
	
	public Server()
	{
		super ("Server");
		setSize (300, 150);
		setLocationRelativeTo (null);
		setDefaultCloseOperation (JFrame.DO_NOTHING_ON_CLOSE);
		
		enterField = new JTextField();
		enterField.setEditable (false);
		enterField.addActionListener
		(
			new ActionListener()
			{
				public void actionPerformed (ActionEvent event)
				{
					sendData (event.getActionCommand());
					enterField.setText ("");
				}
			}
		);
		
		add (enterField, BorderLayout.NORTH);
		
		displayArea = new JTextArea();
		add (new JScrollPane (displayArea), BorderLayout.CENTER);
		
		addWindowListener
		(
			new WindowAdapter()
			{
				public void windowClosing (WindowEvent event)
				{
					closingFlag = true;
					closeConnection();
					dispose();
				}
			}
		);
		
		setVisible (true);
	}
	
	public void runServer()
	{
		try
		{
			server = new ServerSocket (12345, 100);
			
			while (true)
			{
				try
				{
					waitForConnection();
					getStreams();
					processConnection();
				}
				catch (EOFException exception)
				{
					displayMessage ("\nServer terminated connection");
				}
				finally
				{
					closeConnection();
					counter++;
				}
			}
		}
		catch (SocketException exception){}
		catch (IOException exception)
		{
			exception.printStackTrace();
		}
	}
	
	private void waitForConnection() throws IOException
	{
		displayMessage ("Waiting for connection\n");
		connection = server.accept();
		
		displayMessage ("Connection " + counter + " received from: " + connection.getInetAddress().getHostName());
	}
	
	private void getStreams() throws IOException
	{
		output = new ObjectOutputStream (connection.getOutputStream());
		output.flush();
		
		input = new ObjectInputStream (connection.getInputStream());
		
		displayMessage ("\nGot I/O streams\n");
	}
	
	private void processConnection() throws IOException
	{
		String message = "Connection successful";
		sendData (message);
		
		setTextFieldEditable (true);
		
		do
		{
			try
			{
				message = (String) input.readObject();
				displayMessage ("\n" + message);
			}
			catch (ClassNotFoundException exception)
			{
				displayMessage ("\nUnknown object type received");
			}
		} while (!message.equals ("CLIENT>>> TERMINATE"));
	}
	
	private void closeConnection()
	{
		displayMessage ("\nTerminating connection\n");
		setTextFieldEditable (false);
		
		try
		{
			if (output != null)
				output.close();
			if (input != null)
				input.close();
			if (connection != null)
				connection.close();
			if (server != null && closingFlag)
				server.close();
		}
		catch (IOException exception)
		{
			exception.printStackTrace();
		}
	}
	
	private void sendData (String message)
	{
		try
		{
			output.writeObject ("SERVER>>> " + message);
			output.flush();
			displayMessage ("\nSERVER>>> " + message);
		}
		catch (IOException exception)
		{
			displayArea.append ("\nError writing object");
		}
	}
	
	private void displayMessage (final String messageToDisplay)
	{
		SwingUtilities.invokeLater
		(
			new Runnable()
			{
				public void run()
				{
					displayArea.append (messageToDisplay);
				}
			}
		);
	}
	
	private void setTextFieldEditable (final boolean editable)
	{
		SwingUtilities.invokeLater
		(
			new Runnable()
			{
				public void run()
				{
					enterField.setEditable (editable);
				}
			}
		);
	}
}