讲解java网络编程开发基础
1、概述
计算机网络:计算机网络是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统。网络编程的目的:无线电台。传播交流信息。数据交换。通信想要达到这个效果需要什么:1.如何准确地定位网络上的一台主机 192.168.16.124:端口,定位到这个计算机上的某个资源2.找到了这个主机,如何传输数据呢?Javaweb:网页编程 B/S网络编程:TCP/IP C/S
2、网络通信要素
如何实现网络的通信?通信双方的地址:
- IP
- 端口号
- 192.168.16.124:5900
规则:网络通信的协议TCP/IP参考模型小结:
- 1.网络编程中有两个主要的问题如何准确的定位到网络上的一台或者多台主机找到主机之后如何进行通信
- 2.网络编程中的要素IP和端口号 IP网络通信协议 UDP、TCP
- 3.万物皆对象
3、IP地址
==IP地址在 Java.Inet.Address类中==
唯一定位一台网络上的计算机本机 127.0.0.1:localhostIP地址的分类:ipv4 / ipv6公网-私网域名:记忆IP问题IP:www.vip.com
public class lessonIP { public static void main(String[] args) { try { //查询本机 InetAddress inetAddress1 = InetAddress.getByName("127.0.0.1");//try-catch快捷键:ctil+alt+t System.out.println(inetAddress1); InetAddress inetAddress2 = InetAddress.getByName("localhost"); System.out.println(inetAddress2); InetAddress inetAddress3 = InetAddress.getLocalHost(); System.out.println(inetAddress3); InetAddress inetAddress4 = InetAddress.getByName("www.baidu.com"); System.out.println(inetAddress4); //常用方法 System.out.println(inetAddress4.getAddress()); System.out.println(inetAddress4.getHostAddress());//ip System.out.println(inetAddress4.getCanonicalHostName());//规范的名字 System.out.println(inetAddress4.getHostName());//域名,或者自己电脑的 } catch (UnknownHostException e) { e.printStackTrace(); } } }运行结果
4、端口
端口表示计算机上的一个程序的进程:
- 不同的进程有不同的端口号,用来区分软件!
- 被规定 0~65535
- TCP,UDP 每个协议都有65535。
- 单个协议下,端口号不能冲突;多个可以,比如:TCP:80,UDP:80
- 端口分类:
- 公有端口 0 ~ 1023:HTTP:80HTTPS:443FTP:21Telent:23
- 程序注册端口:1024 ~ 49151,分配用户或者程序Tomcat:8080MySql:3306Oracle:1521
- 动态、私有:49152~65535 netstat -ano #查看所有端口 netstat -ano|findstr "5900" #查看指定的端口 tasklist|findstr "8696" #查看指定端口的进程
运行结果
5. 通信协议
-
网络通信协议:速率、传输码率、代码结构、传输控制等等
-
问题:过于复杂解决方案:分层
- TCP/IP协议簇:实际是一组协议
==TCP:用户传输协议UDP:用户数据报协议==
- 出名的协议:TCPIP:网络互连协议
TCP和UDP对比
- TCP:类比于打电话
- 连接、稳定
- 三次握手、四次挥手
- 客户端、服务端
- 传输完成、释放连接、效率低```html/xml最少需要三次,建立稳定连接A:你瞅啥?B:瞅你咋地A:干一场
最少需要四次断开连接:A:我要断开了B:你真的要断开了吗?B:你真的真的要断开了吗?A:我真的断开了
- UDP:类比于发短信 - 不连接、不稳定 - 客户端、服务端:没有明确的界限 - 不管有没有准备好,都可以发给你 ## 6. Java模拟TCP - 需要客户端和服务端 - 客户端 - 连接服务器 Socket - 发送消息 ```java import java.io.IOException; import java.io.OutputStream; import java.net.InetAddress; import java.net.Socket; import java.nio.charset.StandardCharsets; //客户端 public class TcpClientDemo01 { //要知道服务器地址 public static void main(String[] args) { InetAddress severIp; Socket socket=null; OutputStream os=null; { try { //1、要知道服务器的地址,端口号 severIp = InetAddress.getByName("127.0.0.1"); int port=9999; //2、创建一个socket连接 socket = new Socket(severIp, port); //3、发送消息IO流 os = socket.getOutputStream(); os.write("你好".getBytes(StandardCharsets.UTF_8)); } catch (Exception e) { e.printStackTrace(); }finally { if (os!=null){ try { os.close(); } catch (IOException e) { e.printStackTrace(); } } if (socket!=null){ try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } } } } }- 服务端
- 建立服务端口 ServerSocket
- 等待用户的连接 accept
- 接收消息 import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.ServerSocket; import java.net.Socket;
//服务端public class TcpSeverDemo01 {public static void main(String[] args) {ServerSocket serverSocket=null;Socket socket=null;InputStream is=null;ByteArrayOutputStream baos=null;try {//1、我得有一个地址serverSocket = new ServerSocket(9999);//2、等待客户端连接过来socket = serverSocket.accept();//3、读取客户端的消息is = socket.getInputStream();//管道流baos = new ByteArrayOutputStream();byte[] buffer=new byte[1024];int len;while ((len=is.read(buffer))!=-1){baos.write(buffer,0,len);}System.out.println(baos.toString());
} catch (IOException e) { e.printStackTrace(); }finally { //关闭资源 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(); } } } }}
## 模拟文件上传 先将图片复制到项目根目录下 客户端 ```java import java.io.*; import java.net.InetAddress; import java.net.Socket; public class TcpClient { public static void main(String[] args) throws Exception { //1、创建一个socket连接 Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 9000); //2、创建一个输出流 OutputStream os = socket.getOutputStream(); //3、读取文件 FileInputStream fis = new FileInputStream(new File("")); //4、写出文件 byte[] buffer1=new byte[1024]; int len; while ((len=fis.read(buffer1))!=-1){ os.write(buffer1,0,len); } //通知服务器我已经结束了,否则会被下面的输入流捕获 socket.shutdownOutput();//我已经输出完了 //确定接收完毕再断开连接 InputStream inputStream = socket.getInputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buffer2 = new byte[1024]; int len2; while ((len2=inputStream.read(buffer2))!=-1){ baos.write(buffer2,0,len2); } System.out.println(baos.toString()); //5、关闭资源 baos.close(); inputStream.close(); fis.close(); os.close(); socket.close(); } }服务端
import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; import java.nio.charset.StandardCharsets; public class TcpSever { public static void main(String[] args) throws Exception { //1、创建服务 ServerSocket serverSocket = new ServerSocket(9000); //2、监听客户端的连接 Socket socket = serverSocket.accept();//阻塞式监听,会一直等待客户端的连接 //3、获取输入流 InputStream is = socket.getInputStream(); //4、文件输出 FileOutputStream fos = new FileOutputStream(new File("receive.jpg")); byte[] buffer = new byte[1024]; int len; while ((len= is.read(buffer))!=-1){ fos.write(buffer,0,len); } //通知客户端连接完毕 OutputStream outputStream = socket.getOutputStream(); outputStream.write("我接收完毕了,可以断开了".getBytes(StandardCharsets.UTF_8)); //5、关闭资源 fos.close(); is.close(); socket.close(); serverSocket.close(); } }可以看到,项目根目录多了一张图片 “receive.jpg”
7. 初识Tomcat
Tomcat 是什么?Tomcat是一个开源而且免费的 jsp 服务器,属于轻量级应用服务器
8. UDP
发送端
import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; //不需要连接服务器 public class UdpClient { public static void main(String[] args) throws Exception { //1、建立一个Socket DatagramSocket socket = new DatagramSocket(); //2、建个包 String msg="你好呀,服务器"; //发送给谁 InetAddress localhost = InetAddress.getByName("localhost"); int port=9090; //数据,数据的长度起始,发送给谁 DatagramPacket packet = new DatagramPacket(msg.getBytes(),0,msg.getBytes().length,localhost,port); //3、发送包 socket.send(packet); //4、关闭流 socket.close(); } }接收端
import java.net.DatagramPacket; import java.net.DatagramSocket; //还是要等待客户端连接 public class UdpSever { public static void main(String[] args) throws Exception { //开放端口 DatagramSocket socket = new DatagramSocket(9090); //接收数据 byte[] buffer = new byte[1024]; DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length); socket.receive(packet);//阻塞接受 System.out.println(packet.getAddress().getHostAddress()); System.out.println(new String(packet.getData(),0, packet.getLength())); //关闭连接 socket.close(); } }9. UDP实现聊天
基础代码:一方只能发送,一方只能接收
发送方
import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetSocketAddress; public class UdpSender { public static void main(String[] args) throws Exception { DatagramSocket socket = new DatagramSocket(8888); //准备数据:控制台获取 System.In BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); while (true){ String data=reader.readLine(); byte[] datas = data.getBytes(); DatagramPacket packet = new DatagramPacket(datas,0,datas.length,new InetSocketAddress("localhost",6666)); socket.send(packet); if (data.equals("bye")){ break; } } socket.close(); } }接收方
import java.net.DatagramPacket; import java.net.DatagramSocket; public class UdpReceive { public static void main(String[] args) throws Exception { DatagramSocket socket = new DatagramSocket(6666); //准备接受包裹 while (true){ byte[] container = new byte[1024]; DatagramPacket packet = new DatagramPacket(container,0,container.length); socket.receive(packet); //断开连接 byte[] data = packet.getData(); String receivedata = new String(data, 0, packet.getLength()); System.out.println(receivedata); if (receivedata.equals("bye")) { break; } } socket.close(); } }10. URL下载网络资源
- URL:统一资源定位符,定位互联网上的某一个资源,例如 https://www.baidu.com
- DNS解析:将 www.baidu.com(域名) 解析成 xxx.xx.xx.x (ip)
- URL的组成:协议://ip地址:端口/项目名/资源 import java.net.MalformedURLException; import java.net.URL;
public class URLDemo {public static void main(String[] args) throws MalformedURLException {URL url=new URL("http://localhost:8080/helloword/index.jsp");System.out.println(url.getProtocol());//协议System.out.println(url.getHost());//主机ipSystem.out.println(url.getPort());//端口System.out.println(url.getPath());//文件System.out.println(url.getFile());//全路径System.out.println(url.getQuery());//参数}}
准备工作: - 在 E:\tomcatt\apache-tomcat-9.0.60\webapps 目录下新建文件夹 admin (名字随便取),在其中新建 SecurityFile.txt,里面随便写点东西。 - 启动 Tomcat (bin 目录下双击 startup.bat) - 访问网址 http://localhost:8080/admin/SecurityFile.txt 现在,我们要通过 URL 下载这个文件 ```java import java.io.FileOutputStream; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; public class URLDown { public static void main(String[] args) throws Exception { //1、下载地址 URL url = new URL("http://localhost:8080/ldx/SecurityFile.txt"); //2、连接到这个资源 http HttpURLConnection uRLConnection = (HttpURLConnection) url.openConnection(); InputStream inputStream = uRLConnection.getInputStream(); FileOutputStream fos = new FileOutputStream("SecurityFile.txt"); byte[] buffer = new byte[1024]; int len; while ((len=inputStream.read(buffer))!=-1){ fos.write(buffer,0,len); } fos.close(); inputStream.close(); uRLConnection.disconnect(); } }运行即可下载文件(保持 Tomcat 是运行状态才能下载)
下面下载真实网络资源
- 打开网页版网易云
- 点击排行榜,任选一首歌播放
- 按 F12,找到这首歌的 url