要求:UDPProvider 先监听20000端口
UDPSearcher先开启一个线程监听端口30000,等到确定这个线程开始运行了,再发送广播。服务端要能够识别这个广播,并且返回来的信息要能被UDPSearcher识别
public class UDPSearcher{ private static final int LISTEN_PORT = 30000; public static void main()throws IOExceptin,InterruptedException{ System.out.println("UDPSearcher Started."); Listener listener = listen(); sendBroadcast(); System.in.read(); List<Device> devices = listener.getDevicesAndClose(); for(Device device:devices){ System.out.println("Device:" + devive.toString()); } System.out.println("UDPSearcher finished."); } private static Listener listen() throws InterruptedException{ System.out.println("UDPSearcher start listen."); CountDownLatch countDownLatch = new CountDownLatch(1); Listener listener = new Listener(LISTEN_PORT,countDownLatch); listener.start(); countDownLatch.await(); return listener; } private static void sendBroadcast() throws IOException{ System.out.println("UDPSearcher sendBroadcast started."); DatagramSocket ds = new DatagramSocket(); String requestData = MessageCreator.buildWithPort(LISTEN_PORT); byte[] requestDataBytes = requestData.getBytes(); DatagramPacket requestPacket = new DatagramPacket(requestDataBytes, requestDataBytes.length); requestPacket.setAddress(InetAddress.getByName("255.255.255.255")); requestPacket.setPort(20000); ds.send(requestPacket); ds.close(); System.out.println("UDPSearcher sendBroadcast finishes."); } private static class Device{ final int port; final String ip; final String sn; private Device(int port,String ip,String sn){ this.port = port; this.ip = ip; this.sn = sn; } } private static class Listener extends Thread{ private final int listenPort; private final CountDownLatch countDownLatch; private final List<Device> devices = new ArrayList<>(); private boolean done = false; private DatagramSocket ds = null; public Listener(int listenPort,CountDownLatch countDownLatch){ super(); this.listenPort = listenPort; this.countDownLatch = countDownLatch; } public void run(){ super(); countDownLatch.countDown(); try{ ds = new DatagramSocket(listenPort); while(!done){ final byte[] buf = new byte[512]; DatagramPacket receivePack = new DatagramPacket(buf,buf.length); ds.receive(receivePack); String ip =receivePack.getAddress().getHostAddress(); int port = receivePack.getPort(); int dataLen = receivePack.getLength(); String data = new String(receivePack.getData(),0,dataLen); String sn = MessageCreator.parseSn(data); if(sn!=null){ Device device = new Device(port, ip, sn); devices.add(device); } } }catch(){ }finally{ close(); } System.out.println("UDPSearcher listener finished"); } private void close(){ if(ds!=null){ ds.close(); ds=null; } } List<Device> getDevicesAndClose(){ done = true; close(); return devices; } } }main() createSocket() initSocket() todo()
public class Client{ private static final int PORT = 20000; private static final int LOCAL_PORT = 20001; public static void main() throws IOException { Socket socket = createSocket(); //创建Socket initSocket(socket); //初始化socket socket.connect(new InetSocketAddress(Inet4Address.getLocalHost(),port),3000) //发起连接 socket.getLocalAddress(); //本地地址 socket.getLocalPort(); //本地端口 socket.getInetAddress(); //服务端地址 socket.getPort(); //服务端端口 try{ //发送接收数据 todo(socket); }catch(){ System.out.println("异常关闭"); } //释放资源 socket.close(); System.out.println("客户端已退出~"); } private static Socket createSocket() throws IOException{ /* //1-无代理模式,等效于空构造函数 Socket socket = new Socket(Proxy.NO_PROXY); //2-新建一份具有 HTTP 代理的套接字,传输数据将通过www.baidu.com:8080端口转发 Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(Inet4Address.getByName("www.baidu.com"),8800)); socket = new Socket(proxy); //3-新建一个套接字,并且直接【链接】到本地20000的服务器上 socket = new Socket("localhost", PORT); //4-同{3} socket = new Socket(Inet4Address.getLocalHost(),PORT); //5-直接链接到本地20000的服务器上,并且绑定到本地20001端口上 socket = new Socket("localhost",PORT, Inet4Address.getLocalHost(),LOCAL_PORT); socket = new Socket(Inet4Address.getLocalHost(),PORT, Inet4Address.getLocalHost(),LOCAL_PORT); */ Socket socket = new Socket(); socket,bind(new InetSocketAddress(Inet4Address.getLocalHost(),LOCAL_PORT)); return socket; } private static void initSocket(Socket socket) throws SocketExcpetion{ socket.setSoTimeout(2000); //读取超时时间为2秒 socket.setReuseAddress(true); //是否复用未完全关闭的Socket地址,对于指定bind操作后的套接字有效 socket.setTcpNoDelay(true); socket.setKeepAlive(true); socket.setSoLinger(true, 200); socket.setOOBInline(true); socket.setReceiveBufferSize(64*1024*1024); socket.setSendBufferSize(64*1024*1024); socket.setPerformancePreferences(1,1,0); } private static void todo(Socket client)throws IOException{ BufferedReader input = new BufferedReader(new InputStreamReader(System.in)); //socket输出流,并转换为打印流 OutputStream outputStream = client.getOutputStream(); PrintStream socketPrintStream = new PrintStream(outputStream()); //socket输入流,并转换为BufferedReader InputStream inputStream = client.getInputStream(); BufferedReader socketBufferedReader = new BufferedReader(new InputStreamReader(inputStream)); booleam flag = true; do{ String str = input.readLine(); socketPrintStream.println(str); String echo = socketBufferedReader.readLine(); if("".equalsIgnoreCase(echo)){ flag = false; }else{ System.out.println(echo); } }while(flag); socketPrintStream.close(); socketBufferedReader.close(); } }main() createServerSocket() initServerSocket() ClientHander-Thread
public class Server{ private static final int PORT = 20000; public static void main(String[] args) throws IOException{ ServerSocket server = createServerSocket(); initServerSocket(server); server.bind(new InetSocketAddress(Inet4Address.getLocalHost(),PORT),50); server.getInetAddress();//服务器本身的信息 server.getLocalPort(); for(;;){ Socket client = server.accept(); ClientHandler clientHandler = new ClientHandler(client); clientHandler.start(); } } private static ServerSocket createServerSocket() throws IOException{ ServerSocket serverSocket = new ServerSocket(); /* //1-绑定到本地端口20000,并且设置当前可允许等待链接的队列为50 serverSocket = new ServerSocket(PORT); //2-同1 serverSocket = new ServerSocket(PORT,50); //3-同1 serverSocket = new ServerSocket(PORT,50,Inet4Address.getLocalHost()); */ renturn serverSocket(); } private static void initServerSocket(ServerSocket serverSocket)throws IOException{ serverSocket.setReuserAddress(true); serverSocket.setReceiveBufferSize(64*1024*1024); serverSocket.setSoTimeout(2000); serverSocket.setPerformancePreferences(1,1,1); } private static class ClientHandler extends Thread{ private Socket socket; private boolean flag = true; public ClientHandler(Socket socket){ this.socket = socket; } @Override public void run(){ super.run(); socket.getInetAddress(); socket.getPort(); try{ PrintStream socketOutput = new PrintStream(socket.getOutputStream()); BufferedReader socketInput = new BufferedReader(new InputStreamReader(socket.getInputStream())); do{ String str = socketInput.readLine(); if("bye".equalsIgnoreCase(str){ flag = false; socketOutput.println("bye"); }else{ System.out.println(str); socketOutput.println("回送"+str.length()); } }while(flag); socketInput.close(); socketOutput.close(); }catch(){ System.out.println("连接异常断开"); }finally{ CloseUtils.close(socket); } } } }