网络编程
网络通信
- 概念:两台设备之间通过网络实现数据传输。
- java.net包下通过了一系列的类或者接口,供程序员使用,完成网络通信
网络分类(覆盖范围)
- 局域网:覆盖范围最小,仅仅是一个教室或一个机房。
- 城域网:覆盖范围较大,可以覆盖一个城市。
- 广域网:覆盖范围最大,可以覆盖全国,甚至全球,万维网是广域网的代表。
IP地址
概念:用于唯一标识网络中的每台计算机/主机
组成:网络地址+主机地址 如:192.168.16.69.



协议


TCP和UDP的区别

InetAddress类
// 获取本机的InetAddress 对象 InetAddress localhost = InetAddress.getLocalHost(); System.out.println(localhost);// 计算机名/ip地址 // 根据指定的主机名获取对象 InetAddress host = InetAddress.getByName("DESKTOP-49H260O"); System.out.println(host); // 根据域名返回 InetAddress对象 InetAddress host2 = InetAddress.getByName("www.baidu.com"); System.out.println(host2); // 通过 InetAddress对象,获取对应的地址 String host2HostAddress = host2.getHostAddress(); System.out.println(host2HostAddress);// IP地址 // 通过 InetAddress对象,获取对应的主机名/域名 String hostName = host2.getHostName(); System.out.println(hostName);
Socket(TCP编程和UDP编程)

图示


TCP编程
// 服务端 : 上传图片
//1. 服务端在本机监听8888端口 ServerSocket serverSocket = new ServerSocket(8888); System.out.println("服务端在8888端口监听...."); //2. 等待连接 Socket socket = serverSocket.accept(); //3. 读取客户端发送的数据 // 通过Socket得到输入流 BufferedInputStream bis = new BufferedInputStream(socket.getInputStream()); byte[] bytes = StreamUtils.streamToByteArray(bis); //4. 将得到 bytes 数组,写入到指定的路径,就得到一个文件了 String destFilePath = "src\\abc.mp4"; BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFilePath)); bos.write(bytes); bos.close(); // 向客户端回复 "收到图片" // 通过socket 获取到输出流(字符) BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); writer.write("收到图片"); writer.flush();//把内容刷新到数据通道 socket.shutdownOutput();//设置写入结束标记 //关闭其他资源 writer.close(); bis.close(); socket.close(); serverSocket.close();
// 客户端 //客户端连接服务端 8888,得到Socket对象 Socket socket = new Socket(InetAddress.getLocalHost(), 8888); //创建读取磁盘文件的输入流 //String filePath = "e:\\qie.png"; String filePath = "e:\\abc.mp4"; BufferedInputStream bis = new BufferedInputStream(new FileInputStream(filePath)); //bytes 就是filePath对应的字节数组 byte[] bytes = StreamUtils.streamToByteArray(bis); //通过socket获取到输出流, 将bytes数据发送给服务端 BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream()); bos.write(bytes);//将文件对应的字节数组的内容,写入到数据通道 bis.close(); socket.shutdownOutput();//设置写入数据的结束标记 //=====接收从服务端回复的消息===== InputStream inputStream = socket.getInputStream(); //使用StreamUtils 的方法,直接将 inputStream 读取到的内容 转成字符串 String s = StreamUtils.streamToString(inputStream); System.out.println(s); //关闭相关的流 inputStream.close(); bos.close(); socket.close();
// StreamUtils类 /** * 功能:将输入流转换成byte[] * @param is * @return * @throws Exception */ public static byte[] streamToByteArray(InputStream is) throws Exception{ ByteArrayOutputStream bos = new ByteArrayOutputStream();//创建输出流对象 byte[] b = new byte[1024]; int len; while((len=is.read(b))!=-1){ bos.write(b, 0, len); } byte[] array = bos.toByteArray(); bos.close(); return array; } /** * 功能:将InputStream转换成String * @param is * @return * @throws Exception */ public static String streamToString(InputStream is) throws Exception{ BufferedReader reader = new BufferedReader(new InputStreamReader(is)); StringBuilder builder= new StringBuilder(); String line; while((line=reader.readLine())!=null){ //当读取到 null时,就表示结束 builder.append(line+"\r\n"); } return builder.toString(); }
注意:当客户端连接到服务端后,实际上客户端也是通过一个端口和服务端进行通讯的,这个端口是TCP/IP分配的。
UDP编程


代码
//1.创建 DatagramSocket 对象,准备在9998端口 接收数据 DatagramSocket socket = new DatagramSocket(9998); //2. 将需要发送的数据,封装到 DatagramPacket对象 byte[] data = "hello 明天吃火锅~".getBytes(); // //说明: 封装的 DatagramPacket对象 data 内容字节数组 , data.length , 主机(IP) , 端口 DatagramPacket packet = new DatagramPacket(data, data.length, InetAddress.getByName("192.168.12.1"), 9999); socket.send(packet); //3.=== 接收从A端回复的信息 //(1) 构建一个 DatagramPacket 对象,准备接收数据 // 一个数据包最大 64k byte[] buf = new byte[1024]; packet = new DatagramPacket(buf, buf.length); //(2) 调用 接收方法, 将通过网络传输的 DatagramPacket 对象 // 填充到 packet对象 //提示: 当有数据包发送到 本机的9998端口时,就会接收到数据 // 如果没有数据包发送到 本机的9998端口, 就会阻塞等待. socket.receive(packet); //(3) 可以把packet 进行拆包,取出数据,并显示. int length = packet.getLength();//实际接收到的数据字节长度 data = packet.getData();//接收到数据 String s = new String(data, 0, length); System.out.println(s); //关闭资源 socket.close(); System.out.println("B端退出");
//1. 创建一个 DatagramSocket 对象,准备在9999接收数据 DatagramSocket socket = new DatagramSocket(9999); //2. 构建一个 DatagramPacket 对象,准备接收数据 // 在前面讲解UDP 协议时,老师说过一个数据包最大 64k byte[] buf = new byte[1024]; DatagramPacket packet = new DatagramPacket(buf, buf.length); //3. 调用 接收方法, 将通过网络传输的 DatagramPacket 对象 // 填充到 packet对象 // 提示: 当有数据包发送到 本机的9999端口时,就会接收到数据 // 如果没有数据包发送到 本机的9999端口, 就会阻塞等待. System.out.println("接收端A 等待接收数据.."); socket.receive(packet); //4. 可以把packet 进行拆包,取出数据,并显示. int length = packet.getLength();//实际接收到的数据字节长度 byte[] data = packet.getData();//接收到数据 String s = new String(data, 0, length); System.out.println(s); //===回复信息给B端 //将需要发送的数据,封装到 DatagramPacket对象 data = "好的, 明天见".getBytes(); //说明: 封装的 DatagramPacket对象 data 内容字节数组 , data.length , 主机(IP) , 端口 packet = new DatagramPacket(data, data.length, InetAddress.getByName("192.168.12.1"), 9998); socket.send(packet);//发送 //5. 关闭资源 socket.close(); System.out.println("A端退出...");

浙公网安备 33010602011771号