package org.kne.cloud.network;

import java.io.Closeable;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.function.Consumer;

public class SocketListener implements Closeable,AutoCloseable{
	protected ServerSocket serverSocket;
	public ServerSocket getServerSocket() {
		return serverSocket;
	}

	private volatile boolean flag=true;
	
	private volatile Consumer<Socket>con;
	private Runnable r=new Runnable() {
		@Override
		public void run() {
			while(flag){
				try {
					Socket soce=serverSocket.accept();
					ThreadTool.makeVThreadIfSupport("端口监听线程",()->{
							if(con!=null) {
								try {
						con.accept(soce);
								}catch(Exception e) {
									e.printStackTrace();
									try {
										soce.close();
									} catch (IOException er) {
										er.printStackTrace();
									}
								}
							}else {
								try {
									soce.close();
								} catch (IOException e) {
									e.printStackTrace();
								}
						}
					}).start();
				}catch(SocketException e) {
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	};
	private MultiProtocolSocketAddress multiProtocolSocketAddress;
	
	public SocketListener(MultiProtocolSocketAddress multiProtocolSocketAddress) throws  IOException {
		this.multiProtocolSocketAddress = multiProtocolSocketAddress;
			open();
	}
	public SocketListener(ServerSocket tserverSocket) throws  IOException {
		this.serverSocket=tserverSocket;
			open();
	}
	protected void open() throws UnknownHostException, IOException  {
		if(serverSocket==null)
			serverSocket= multiProtocolSocketAddress.listenServerSocket();
		ThreadTool.makeVThread("端口监听线程", r).start();
	}
	public void close() {
		flag=false;
		if(serverSocket!=null) {
			try {
				serverSocket.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			serverSocket=null;
		}
	}
	
	

	public MultiProtocolSocketAddress getMultipurposeSocketAddress() {
		return multiProtocolSocketAddress;
	}

	public Consumer<Socket> getCon() {
		return con;
	}

	public void setCon(Consumer<Socket> con) {
		this.con = con;
	}
	
}
