练习-Socket-1

it2024-08-05  40

UDP单播

UDPSearcher:搜索者,向服务端请求UDP数据,不指定自己的端口,就以发送端口接收UDPProvider:提供者

要求:UDPProvider 先监听20000端口

UDPSearcher

public class UDPSearcher{ public static void main(String[] args) throws IOException{ System.out.println("UDPSearcher Started"); DatagramSocket datagramSocket = new DatagramSocket(); String requestData = "hello world"; byte[] requestBytes = requestData.getBytes(); DatagramPacket requestPacket = new DatagramPacket(requestBytes,requestBytes.length); requestPacket.setAddress(InetAddress.getLocalHost()); requestPacket.setPort(20000); datagramSocket.send(requestPacket); final byte[] buf = new byte[512]; DatagramPacket receivePacket = new DatagramPacket(buf,buf.length); datagramSocket.receive(receivePacket); String ip = receivePacket.getAddress().getHostAddress(); int port = receivePacket.getPort(); int datalen = receivePacket.getLength(); String data = new String(receivePacket.getData(),0,datalen); System.out.println("UDPSearcher finish!"); datagramSocket.close(); } }

UDPProvider

public class UDPProvider{ public static void main(String[] args) throws IOException{ System.out.println("UDPProvider Started!"); DatagramSocket datagramSocket = new DatagramSocket(20000); final byte[] buf = new byte[512]; DatagramPacket receivePacket = new DatagramPacket(buf,buf.length); datagramSocket.receive(receivePacket); String ip = receivePacket.getAddress().getHostAddress(); int port = receivePacket.getPort(); int dataLen = receivePacket.getLength(); String data = new String(receivePacket.getData(),0,datalen); //回送数据 String responseData = "data len:"+datalen; byte[] responseBytes = responseData.getBytes(); DatagramPacket responsePacket = new DatagramPacket(responseBytes, responseBytes.length, receivePacket.getAddress(), receivePacket.getPort()); datagramSocket.send(responsePacket); System.out.println("UDPProvider finish"); datagramSocket.close(); } }

UDP广播

MessageCreatorUDPProviderUDPSearcher

MessageCreator

public class MessageCreator{ private static final String SN_HEADER = "收到暗号,我是SN:"; private static final String PORT_HEADER = "这是暗号,请回电PORT:"; //Searcher发送的数据 public static String buildWithPort(int port){ return PORT_HEADER + PORT; } //Provider解析的数据 public static int parsePort(String data){ if(data.startsWith(PORT_HEADER)){ return Integer.parseInt(data.substring(PORT_HEADER.length())); } return -1; } //Provider发送的数据 public static Strin buildWithSn(String sn){ return SN_HEADER + sn; } //Searcher解析的数据 public static String parseSn(String data){ if(data.startsWith(SN_HEADER)){ return data.substring(SN_HEADER.length()); } return null; } }

UDPProvider

public class UDPProvider{ public static void main(String[] args) throw IOException{ String sn = UUID.randomUUID().toString(); Provider provider = new Provider(sn); provider.start(); System.in.read(); provider.exit(); } private static class Provider extends Thread{ private final String sn; private boolean done = false; private DatagramSocket ds = null; public Provider(String sn){ super(); this.sn = sn; } @Override public void run(){ super.run(); System.out.println("UDPProvider Started"); try{ ds = new DatagramSocket(20000); 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); int responsePort = MessageCreator.parsePort(data); if(responsePort != -1){ String responseData = MessageCreator.buildWithSn(sn); byte[] responseData = responseData.getBytes(); DatagramPacket responsePacket = new DatagramPacket( responseDataBytes, responseDataByted.length, receivePack.getAddress(), responsePort); ds.send(responsePacket); } } }catch(){ }finally{ close(); } System.out.println("UDPProvider finished"); } void exit(){ done = true; close(); } private void close(){ if(ds!=null){ ds.close(); ds = null; } } } }

UDPSearcher

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; } } }

TCP数据传输

客户端

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); } } } }
最新回复(0)