• 第十六章 网络编程


    16、网络编程
    16.1 网络编程概述 1课时
    16.2 通讯要素 1课时
    16.3 InetAddress类 1课时
    16.4 TCP网络通信 1课时
    16.5 UDP网络通信 1课时
    16.6 NIO中的非阻塞式网络通信 1课时
    16.7 URL编程 1课时

    16-1 网络编程概述

    16-2 网络通信要素

    16-3 InetAddress类

    InetAddress类的案例

    import java.net.InetAddress;
    import java.net.UnknownHostException;
    
    /**
     * 一、要想实现网络通信,需要解决两个问题:
     * 1.如何准确的定位互联网上的一台或多台主机
     * 2.如何实现可靠而高效的数据传输
     * 
     * 二、网络通信的两个要素:
     * 1.使用IP地址,定位网络中的主机
     * 2.遵循相关的网络通信协议
     * 
     * 三、针对要素一:
     * 1.IP:一个ip地址,对应着网络中的一台主机。 "192.168.20.16"   "127.0.0.1"--本地回路地址
     *   使用InetAddress类来代表IP,一个InetAddress类的对象,就代表着一个具体的ip地址。
     * 
     * 2.如何实例化InetAddress:①getByName(String hostName) ②getLocalHost()
     * 		
     * 3.域名: www.baidu.com   www.jd.com   www.mi.com  www.vip.com
     *        www.facebook.com
     *        localhost对应着127.0.0.1
     * 
     * 4.InetAddress类的常用方法:getHostName() / getHostAddress()
     * 
     * 
     * 5.端口号标识正在计算机上运行的进程(程序)
     *  注意:不同的进程有不同的端口号
     *  常见的端口号: http:80   tomcat : 8080   mysql:3306  oracle:1521等
     * 
     */
    public class InetAddressTest {
    	public static void main(String[] args) {
    		
    		//1.实例化
    		try {
    			//getByName()
    			InetAddress inetAddress = InetAddress.getByName("192.168.10.16");
    			System.out.println(inetAddress);
    			
    			InetAddress inetAddress1 = InetAddress.getByName("www.tzy.com");
    			System.out.println(inetAddress1);//www.tzytzy.top/100.151.2.166
    			//getLocalHost()
    			InetAddress localAddress = InetAddress.getLocalHost();
    			System.out.println(localAddress);
    			
    			
    			//2.两个方法
    			System.out.println(inetAddress1.getHostName());//www.tzytzy.top
    			
    			System.out.println(inetAddress1.getHostAddress());//100.151.2.166
    			
    		} catch (UnknownHostException e) {
    			e.printStackTrace();
    		}
    		
    	}
    }
    

    16-4 TCP网络通信

    TCP案例

    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.InetAddress;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.net.UnknownHostException;
    
    import org.junit.Test;
    
    //使用TCP的网络通信:1.客户端发送内容给服务端,服务端将内容打印到控制台上。
    public class TCPTest1 {
    
    	// 客户端
    	@Test
    	public void client() {
    		Socket socket = null;
    		OutputStream os = null;
    		try {
    			// 1.创建一个Socket,指明服务器端的ip及端口号
    			socket = new Socket(InetAddress.getByName("127.0.0.1"), 9090);
    
    			// 2.通过socket获取一个输出流
    			os = socket.getOutputStream();
    			// 3.输出数据
    			os.write("我是客户端要发送的数据".getBytes());
    		} catch (Exception e) {
    			e.printStackTrace();
    		} finally {
    			if (os != null) {
    				// 4.关闭资源
    				try {
    					os.close();
    				} catch (IOException e) {
    					e.printStackTrace();
    				}
    
    			}
    			if (socket != null) {
    				try {
    					socket.close();
    				} catch (IOException e) {
    					e.printStackTrace();
    				}
    
    			}
    		}
    
    	}
    
    	// 服务器端
    	@Test
    	public void server() {
    		ServerSocket serverSocket = null;
    		Socket socket = null;
    		InputStream is = null;
    		ByteArrayOutputStream baos = null;
    		try {
    			//1.创建serverSocket,需要指明自己的端口号
    			serverSocket = new ServerSocket(9090);
    			//2.接口客户发送的Socket
    			socket = serverSocket.accept();
    			//3.读取发送来的数据,并显示在控制台上
    			is = socket.getInputStream();
    			baos = new ByteArrayOutputStream();
    			byte[] buffer = new byte[20];
    			int len;
    			while ((len = is.read(buffer)) != -1) {
    				baos.write(buffer, 0, len);
    			}
    			System.out.print(baos.toString());
    			System.out.println("收到了来自于" + socket.getInetAddress().getHostAddress() + "的数据");
    			
    		} catch (IOException e) {
    			e.printStackTrace();
    		} finally {
    			//4.关闭资源
    			if (baos != null) {
    				try {
    					baos.close();
    				} catch (IOException e) {
    					e.printStackTrace();
    				}
    
    			}
    			if (is != null) {
    				try {
    					is.close();
    				} catch (IOException e) {
    					e.printStackTrace();
    				}
    
    			}
    			if (socket != null) {
    				try {
    					socket.close();
    				} catch (IOException e) {
    					e.printStackTrace();
    				}
    
    			}
    			if (serverSocket != null) {
    
    				try {
    					serverSocket.close();
    				} catch (IOException e) {
    					e.printStackTrace();
    				}
    
    			}
    		}
    
    	}
    
    }
    

    import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket;
    import org.junit.Test;
    
    //使用TCP的网络通信:2.客户端发送文件给服务器端,服务器端保存在本地。
    
    public class TCPTest2 {
    	
    	//客户端
    	//异常应该使用try-catch-finally处理
    	@Test
    	public void client() throws Exception{
    		//1.
    		Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 9090);
    		//2.
    		OutputStream os = socket.getOutputStream();
    		//3.
    		FileInputStream fis = new FileInputStream("beauty.jpg");
    		//4.读写数据
    		byte[] buffer = new byte[20];
    		int len;
    		while((len = fis.read(buffer)) != -1){
    			os.write(buffer, 0, len);
    			
    		}
    		//5.
    		fis.close();
    		os.close();
    		socket.close();
    		
    	}
    	
    	//服务器端
    	@Test
    	public void server() throws IOException{
    		//1.
    		ServerSocket serverSocket = new ServerSocket(9090);
    		
    		//2.
    		Socket socket = serverSocket.accept();
    		//3.
    		InputStream is = socket.getInputStream();
    		
    		//4.
    		FileOutputStream fos = new FileOutputStream("beauty1.jpg");
    		
    		//5.读写数据
    		byte[] buffer = new byte[20];
    		int len;
    		while((len = is.read(buffer)) != -1){
    			fos.write(buffer, 0, len);
    		}
    		
    		//6.
    		fos.close();
    		is.close();
    		socket.close();
    		serverSocket.close();
    	}
    }
    

    import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket;
    import org.junit.Test;
    
    //使用TCP的网络通信:3.客户端发送文件给服务器端,服务器端保存在本地。同时,服务器发送反馈给客户端
    public class TCPTest3 {
    	// 客户端
    	// 异常应该使用try-catch-finally处理
    	@Test
    	public void client() throws Exception {
    		// 1.
    		Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 9090);
    		// 2.
    		OutputStream os = socket.getOutputStream();
    		// 3.
    		FileInputStream fis = new FileInputStream("beauty.jpg");
    		// 4.读写数据
    		byte[] buffer = new byte[20];
    		int len;
    		while ((len = fis.read(buffer)) != -1) {
    			os.write(buffer, 0, len);
    
    		}
    		
    		//表明,输出结束
    		socket.shutdownOutput();
    		
    		//接收来自于服务器端的数据
    		//练习:使用ByteArrayOutputStream更合适
    		InputStream is = socket.getInputStream();
    		byte[] buf = new byte[200];
    		int len1;
    		while((len1 = is.read(buf)) != -1){
    			System.out.print(new String(buf,0,len1));
    		}
    		
    		
    		// 5.
    		is.close();
    		fis.close();
    		os.close();
    		socket.close();
    
    	}
    
    	// 服务器端
    	@Test
    	public void server() throws IOException {
    		// 1.
    		ServerSocket serverSocket = new ServerSocket(9090);
    
    		// 2.
    		Socket socket = serverSocket.accept();
    		// 3.
    		InputStream is = socket.getInputStream();
    
    		// 4.
    		FileOutputStream fos = new FileOutputStream("beauty2.jpg");
    
    		// 5.读写数据
    		byte[] buffer = new byte[20];
    		int len;
    		while ((len = is.read(buffer)) != -1) {
    			fos.write(buffer, 0, len);
    		}
    		
    		System.out.println("hello!");
    		
    		//发送反馈给客户端
    		OutputStream os = socket.getOutputStream();
    		os.write("我收到了你的照片,很漂亮!".getBytes());
    		
    
    		// 6.
    		os.close();
    		fos.close();
    		is.close();
    		socket.close();
    		serverSocket.close();
    	}
    }
    

    16-5 UDP网络通信

    发送端
    DatagramSocket ds = new DatagramSocket();
    byte[] by = “hello,xxx.com”.getBytes();
    DatagramPacket dp = new DatagramPacket(by,0,by.length,
    		InetAddress.getByName(“127.0.0.1”),10000);
    ds.send(dp);
    ds.close();
    
    接收端

    在接收端,要指定监听的端口。

    DatagramSocket ds = new DatagramSocket(10000);
    byte[] by = new byte[1024];
    DatagramPacket dp = new DatagramPacket(by,by.length);
    ds.receive(dp);
    String str = new String(dp.getData(),0,dp.getLength());
    System.out.println(str+"--"+dp.getAddress());
    ds.close();
    

    UDP案例

    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    import java.net.SocketException;
    
    import org.junit.Test;
    
    //UDP的网络通信
    public class UDPTest {
    
    	//发送端
    	@Test
    	public void sender() throws Exception{
    		DatagramSocket socket = new DatagramSocket();
    		
    		//提供数据报。在数据报中封装要发送的数据,以及要发送到的接收端的ip地址和端口号。
    		byte[] buf = "我是UDP方式发送的导弹".getBytes();
    		DatagramPacket pack = new DatagramPacket(buf, 0, buf.length, InetAddress.getByName("127.0.0.1"), 8989);
    		
    		socket.send(pack);
    		
    		socket.close();
    		
    	}
    	
    	//接收端
    	@Test
    	public void receiver() throws Exception{
    		
    		DatagramSocket socket = new DatagramSocket(8989);
    		byte[] buf = new byte[200];
    		DatagramPacket pack = new DatagramPacket(buf, 0, buf.length);
    		
    		socket.receive(pack);
    		//pack.getData():获取数据报中封装的数组
    		//pack.getLength():获取写入到数组中的数据的长度
    		System.out.println(new String(pack.getData(), 0, pack.getLength()));
    		
    		socket.close();
    	}
    }
    

    16-6 NIO中的非阻塞式网络通信

    NIO实现阻塞式

        import java.io.IOException;
    import java.net.InetAddress;
    import java.net.InetSocketAddress;
    import java.nio.ByteBuffer;
    import java.nio.channels.FileChannel;
    import java.nio.channels.ServerSocketChannel;
    import java.nio.channels.SocketChannel;
    import java.nio.file.Paths;
    import java.nio.file.StandardOpenOption;
    
    import org.junit.Test;
    
    //TCP网络编程1:使用NIO中的Channel + Buffer 实现客户端给服务器端发送文件.
    public class BlockingNIOTest {
    	
    	@Test
    	public void client() throws Exception{
    		InetAddress addr = InetAddress.getByName("127.0.0.1");
    		SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress(addr, 9090));
    		
    		FileChannel fileChannel = FileChannel.open(Paths.get("beauty.jpg"), StandardOpenOption.READ);
    		
    		//使用Channel实现数据的读写
    		ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
    		while(fileChannel.read(byteBuffer) != -1){
    			byteBuffer.flip();
    			socketChannel.write(byteBuffer);
    			byteBuffer.clear();
    		}
    		
    		fileChannel.close();
    		socketChannel.close();
    		
    		
    	}
    	
    	@Test
    	public void server() throws Exception{
    		ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
    		//绑定端口号
    		serverSocketChannel.bind(new InetSocketAddress(9090));
    		
    		SocketChannel socketChannel = serverSocketChannel.accept();
    		
    		//使用FileChannel和SocketChannel实现数据的读写
    		FileChannel fileChannel = FileChannel.open(Paths.get("beauty3.jpg"), StandardOpenOption.WRITE,StandardOpenOption.CREATE);
    		ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
    		while(socketChannel.read(byteBuffer) != -1){
    			byteBuffer.flip();
    			fileChannel.write(byteBuffer);
    			byteBuffer.clear();
    		}
    		
    		fileChannel.close();
    		socketChannel.close();
    		serverSocketChannel.close();
    		
    	}
    }
    

    import java.net.InetAddress; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.nio.file.Paths; import java.nio.file.StandardOpenOption;
    import org.junit.Test;
    
    //TCP网络编程2:使用NIO中的Channel + Buffer 实现客户端给服务器端发送文件,同时,服务器在接收完毕以后,给予反馈
    public class BlockingNIOTest1 {
    	
    	
    	@Test
    	public void client() throws Exception{
    		InetAddress addr = InetAddress.getByName("127.0.0.1");
    		SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress(addr, 9090));
    		
    		FileChannel fileChannel = FileChannel.open(Paths.get("beauty.jpg"), StandardOpenOption.READ);
    		
    		//使用Channel实现数据的读写
    		ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
    		while(fileChannel.read(byteBuffer) != -1){
    			byteBuffer.flip();
    			socketChannel.write(byteBuffer);
    			byteBuffer.clear();
    		}
    		
    		//关闭数据的输出
    		socketChannel.shutdownOutput();
    		
    		
    		//接收来自于服务器端的数据
    		socketChannel.read(byteBuffer);
    		byteBuffer.flip();
    		System.out.println(new String(byteBuffer.array(),0,byteBuffer.limit()));
    		byteBuffer.clear();//可有可无
    		
    		
    		fileChannel.close();
    		socketChannel.close();
    		
    		
    	}
    	
    	@Test
    	public void server() throws Exception{
    		ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
    		//绑定端口号
    		serverSocketChannel.bind(new InetSocketAddress(9090));
    		
    		SocketChannel socketChannel = serverSocketChannel.accept();
    		
    		//使用FileChannel和SocketChannel实现数据的读写
    		FileChannel fileChannel = FileChannel.open(Paths.get("beauty4.jpg"), StandardOpenOption.WRITE,StandardOpenOption.CREATE);
    		ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
    		while(socketChannel.read(byteBuffer) != -1){
    			byteBuffer.flip();
    			fileChannel.write(byteBuffer);
    			byteBuffer.clear();
    		}
    		
    		//服务器端在接收完毕数据以后,发送反馈给客户端
    		byteBuffer.put("人家已收到了你的情意,么么".getBytes());
    		byteBuffer.flip();
    		socketChannel.write(byteBuffer);
    		byteBuffer.clear();//可有可无
    		
    		
    		fileChannel.close();
    		socketChannel.close();
    		serverSocketChannel.close();
    		
    	}
    	
    }
    

    NIO实现非阻塞式

    /**
     * 使用NIO实现非阻塞式的TCP的网络传输:实现客户端给服务器端发送文件,同时,服务器在接收完毕以后,给予反馈
     * 
     * 1.选择器(Selector) 是 SelectableChannel 对象的多路复用器
     * 2.Selector 可以同时监控多个 SelectableChannel 的 IO 状况,也就是说,利用 Selector 
     * 可使一个单独的线程管理多个 Channel。
     * 3.Selector 是非阻塞 IO 的核心。
     * 4.SelectableChannel
     * 		|-----SocketChannel
     * 		|-----ServerSocketChannel
     * 		|-----DatagramChannel
     *
     */
    
    public class NonBlockingNIOTest {
    	
    	@Test
    	public void client() throws Exception{
    		
    		InetAddress addr = InetAddress.getByName("127.0.0.1");
    		SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress(addr, 9090));
    		
    		//设置当前Channel为非阻塞式的
    		socketChannel.configureBlocking(false);
    		
    		Scanner scanner = new Scanner(System.in);
    		
    		//使用Channel实现数据的读写
    		ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
    		while(scanner.hasNext()){
    			String line = scanner.nextLine();
    			SocketAddress address = socketChannel.getLocalAddress();
    			byteBuffer.put((address + "-" + new Date() + ":
    " + line).getBytes());
    			byteBuffer.flip();
    			socketChannel.write(byteBuffer);
    			byteBuffer.clear();
    			
    		}
    		
    		socketChannel.close();
    		
    	}
    	
    	
    	@Test
    	public void server() throws Exception{
    		
    		ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
    		
    		//serverSocketChannel设置为非阻塞的
    		serverSocketChannel.configureBlocking(false);
    		//设置serverSocketChannel的端口号
    		serverSocketChannel.bind(new InetSocketAddress(9090));
    		
    		//获取Selector
    		Selector selector = Selector.open();
    		//注册Selector,表明可以接收客户端的数据
    		serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
    		SocketChannel socketChannel = null;
    		while(selector.select() > 0){
    			
    			Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
    			while(iterator.hasNext()){
    				SelectionKey selectionKey = iterator.next();
    				
    				if(selectionKey.isAcceptable()){//表示当前可以接收客户端数据
    					
    					//接收到客户端发送来的socketChannel
    					socketChannel = serverSocketChannel.accept();
    					//设置socketChannel为非阻塞的
    					socketChannel.configureBlocking(false);
    					//注册
    					socketChannel.register(selector, SelectionKey.OP_READ);
    					
    				}else if(selectionKey.isReadable()){//表示可以读取客户端的数据
    					
    					//读取SocketChannel中的数据
    					socketChannel = (SocketChannel) selectionKey.channel();
    					
    					ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
    					while(socketChannel.read(byteBuffer) > 0){
    						byteBuffer.flip();
    						System.out.println(new String(byteBuffer.array(),0,byteBuffer.limit()));
    						byteBuffer.clear();
    						
    					}
    					
    				}
    					iterator.remove();
    			}
    		
    			
    		}
    		
    		socketChannel.close();
    		serverSocketChannel.close();
    		selector.close();
    		
    	}
    	
    }
    

    import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.DatagramChannel; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.util.Date; import java.util.Iterator; import java.util.Scanner;
    import org.junit.Test;
    //针对UDP,使用NIO实现非阻塞式的网络通信
    public class NonBlockingNIOTest1 {
    	
    	@Test
    	public void send() throws IOException{
    		DatagramChannel dc = DatagramChannel.open();
    		
    		dc.configureBlocking(false);
    		
    		ByteBuffer buf = ByteBuffer.allocate(1024);
    		
    		Scanner scan = new Scanner(System.in);
    		
    		while(scan.hasNext()){
    			String str = scan.nextLine();
    			buf.put((new Date().toString() + ":
    " + str).getBytes());
    			buf.flip();
    			dc.send(buf, new InetSocketAddress("127.0.0.1", 9898));
    			buf.clear();
    		}
    		
    		dc.close();
    	}
    	
    	
    	@Test
    	public void receive() throws IOException{
    		DatagramChannel dc = DatagramChannel.open();
    		
    		dc.configureBlocking(false);
    		
    		dc.bind(new InetSocketAddress(9898));
    		
    		Selector selector = Selector.open();
    		
    		dc.register(selector, SelectionKey.OP_READ);
    		
    		while(selector.select() > 0){
    			Iterator<SelectionKey> it = selector.selectedKeys().iterator();
    			
    			while(it.hasNext()){
    				SelectionKey sk = it.next();
    				
    				if(sk.isReadable()){
    					ByteBuffer buf = ByteBuffer.allocate(1024);
    					
    					dc.receive(buf);
    					buf.flip();
    					System.out.println(new String(buf.array(), 0, buf.limit()));
    					buf.clear();
    				}
    			}
    			
    			it.remove();
    		}
    		dc.close();
    	}
    
    }
    

    16-7 URL编程

    /**
     * 1.URL(Uniform Resource Locator):统一资源定位符,它表示 Internet 上某一资源的地址。
     * 
     * 2.举例:http://127.0.0.1:8080/examples/ym.jpg
     *       协议 网络主机  端口号 工程 文件
     * 
     * 3.如何实例化URL
     * 
     *
     */
    public class URLTest {
    	public static void main(String[] args) {
    		HttpURLConnection conn = null;
    		InputStream is = null;
    		FileOutputStream fos = null;
    		try {
    			//1.实例化
    //			URL url = new URL("http://127.0.0.1:8080/examples/ym.jpg?name=Tom");
    			URL url = new URL("http://127.0.0.1:8080/examples/ym.jpg");
    			
    			//2.常用方法
    			/*
    			public String getProtocol(  )     获取该URL的协议名
    			public String getHost(  )           获取该URL的主机名
    			public String getPort(  )            获取该URL的端口号
    			public String getPath(  )           获取该URL的文件路径
    			public String getFile(  )             获取该URL的文件名
    			public String getQuery(   )        获取该URL的查询名
    
    			 */
    //			System.out.println(url.getProtocol());
    //			System.out.println(url.getHost());
    //			System.out.println(url.getPort());
    //			System.out.println(url.getPath());
    //			System.out.println(url.getFile());
    //			System.out.println(url.getQuery());
    			
    			//3.如何下载对应的url资源
    			conn = (HttpURLConnection) url.openConnection();
    			
    			conn.connect();
    			
    			is = conn.getInputStream();
    			fos = new FileOutputStream("ym1.jpg");
    			byte[] buffer = new byte[1024];
    			int len;
    			while((len = is.read(buffer)) != -1){
    				fos.write(buffer, 0, len);
    			}
    			
    		} catch (Exception e) {
    			e.printStackTrace();
    		}finally{
    			if(conn != null){
    				conn.disconnect();
    			}
    			
    			if(is != null){
    				try {
    					is.close();
    				} catch (IOException e) {
    					e.printStackTrace();
    				}
    			}
    			if(fos != null){
    				try {
    					fos.close();
    				} catch (IOException e) {
    					e.printStackTrace();
    				}
    			}
    			
    		}
    		
    		
    		
    		
    	}
    }
    

  • 相关阅读:
    设计模式(18)>职责链模式 小强斋
    设计模式(17)>中介者模式 小强斋
    设计模式(16)>原型模式 小强斋
    设计模式(20)>状态模式 小强斋
    设计模式(15)>桥接模式 小强斋
    设计模式(18)>职责链模式 小强斋
    堆栈的工作原理
    掌握udev
    Qt Model/View 学习笔记 (七)
    Qt Model/View 学习笔记 (六)
  • 原文地址:https://www.cnblogs.com/ttzzyy/p/9744737.html
Copyright © 2020-2023  润新知