• 网络编程详细介绍()


    • 概述

    计算机网络

    把分布在不同地理区域的计算机与专门的外部设备用通信线路互连成一个规 模大、功能强的网络系统,从而使众多的计算机可以方便地互相传递信息、 共享硬件、软件、数据信息等资源。 

    网络编程

    通过网络协议直接或间接地与其它计算机实现数据交换,进行通讯。 

    • 网络通讯三要素

    要素一:IP地址

    说明

    • 要想让网络中的计算机能够 互相通信,必须为每台计算机指定一个标识号, 通过这个标识号来指定要接收数据的计算机和识别发送的计算机,而P地址就是这个标识号。也就是设备的标识端口
    • IP地址是Internet 上的计算机唯一的标识(通信实体)

    IP地址分类方式

    IPV4 和 IPV6 分类方式:

    • IPv4: 是给每个连接在网络上的主机分配一个32bit地址。 按照TCP/IP规定,IP地址用二进制来表示,每个IP地址长32bit,也就是4个字节。例如一个采用二进制形式的IP地址是 “1100000  1010100 00000001 01000010* , 这么长的地址,处理起来也太费劲了。为了方便使用,IP地址经常被写成十进制的形式,中间使用符号"."分隔不同的字节。于是,上面的IP地址可以表示为 “192.168.1.66" 。IP地址的这种表示法叫做“点分十进制表示法”,这显然比1和0容易记忆得多。大概42亿,30亿都在北美,亚洲4亿。2011年初已 经用尽
    • IPv6: 由于互联网的蓬勃发展, IP地址的需求量愈来愈大,但是网络地址资源有限,使得IP的分配越发紧张。为了扩大地址空间,通过IPv6重新定义地址空间,采用128位地址长度,每16个字节一组, 分成8组十六进制数,如:3ffe:3201:1401:1280:c8ff:fe4d:db39:1984。这样就解决了网络地址资源数量不够的问题

    公网地址(万维网使用)和私有地址(局域网使用)分类方式:

    • 公网地址:基于因特网,通过TCP/IP应用层协议中的HTTP协议提供的服务,浏览器使用HTTP协议与服务器进行通信,发送数据请求,获取HTML文件,再通过浏览器解析,最终以网页的形式呈现给用户。
    • 私有地址:192.168. 开头的就是私有址址,范围即为192.168.0.0--192.168.255.255,专门为组织机构内部使用,因为不便于记忆,就有了域名的出现(如:www.baidu.com)。

    特殊IP地址

    本地回路地址:127.0.0.1 对应着:localhost

    IP常用命令

    • ipconfig:查看本机IP地址
    • ping IP地址:检查网络是否连通

    Java中IP地址操作类——InetAddress

    InetAddress类:一个该类的对象就代表一个IP地址对象。 

    InetAddress类常用方法: 

    • static InetAddress getLocalHost():获得本地主机IP地址对象。
    • static InetAddress getByName(String host):根据IP地址字符串或主机名获得对应的IP地址对象。
    • String getHostName():获得主机名。
    • String getHostAddress(): 获得IP地址字符串。
      1. InetAddress inetAddress = InetAddress.getByName("192.168.10.14");
      2. System.out.println(inetAddress);
      3. InetAddress inetAddress1 = InetAddress.getByName("www.baidu.com");
      4. System.out.println(inetAddress1);
      5. //获取本地IP
      6. InetAddress inetAddress2 = InetAddress.getByName("127.0.0.1");
      7. System.out.println(inetAddress2);
      8. //获取本地IP
      9. InetAddress inetAddress3 = InetAddress.getLocalHost();
      10. System.out.println(inetAddress3);
      11. //获得主机名
      12. System.out.println(inetAddress3.getHostName());
      13. //获得IP地址字符串
      14. System.out.println(inetAddress3.getHostAddress());

      要素二:端口号

    说明

    • 网络的通信,本质上是两个应用程序的通信。每台计算机都有很多的应用程序,那么在网络通信时,如何区分这些应用程序呢?如果说IP地址可以唯一标识网络中的设备 ,那么端口号就可以唯一标识设备中的应用程序了。也就是应用程序的标识 
    • 不同的进程有不同的端口号
    • 被规定为一个 16 位的整数 0~65535

    端口分类

    • 公认端口:0~1023。被预先定义的服务通信占用(如:HTTP占用端口 80,FTP占用端口21,Telnet占用端口23)
    • 注册端口:1024~49151。分配给用户进程或应用程序。(如:Tomcat占 用端口8080,MySQL占用端口3306,Oracle占用端口1521等)。
    • 动态/私有端口:49152~65535。 
    • 端口号与IP地址的组合得出一个网络套接字:Socket
    1. @Test
    2. public void clientTest2() throws IOException {
    3. InetAddress localHost = InetAddress.getLocalHost();
    4. Socket socket = new Socket(localHost,6677);
    5. OutputStream os = socket.getOutputStream();
    6. os.write("您好,我是客户端".getBytes());
    7. os.close();
    8. socket.close();
    9. }

    要素三:通信协议

    说明

    • 通过计算机网络可以使多台计算机实现连接,位于同一个网络中的计算机在进行连接和通信时需要遵守定的规则,这就好比在道路中行驶的汽车一定要遵守交通规则一样。在计算机网络中,这些连接和通信的规则被称为网络通信协议,它对数据的传输格式、传输速率、传输步骤等做了统规定,通信双方必须同时遵守才能完成数据交换。
    • 传输层协议中有两个非常重要的协议:
    1. 传输控制协议TCP(Transmission Control Protocol)
    2. 用户数据报协议UDP(User Datagram Protocol)

    Socket

    •  利用套接字(Socket)开发网络应用程序早已被广泛的采用,以至于成为事实 上的标准。
    • 网络上具有唯一标识的IP地址和端口号组合在一起才能构成唯一能识别的标 识符套接字。
    • 通信的两端都要有Socket,是两台机器间通信的端点。
    • 网络通信其实就是Socket间的通信。
    • Socket允许程序把网络连接当成一个流,数据在两个Socket间通过IO传输。
    • 一般主动发起通信的应用程序属客户端,等待通信请求的为服务端。
    • Socket分类:
    1. 流套接字(stream socket):使用TCP提供可依赖的字节流服务
    2. 数据报套接字(datagram socket):使用UDP提供“尽力而为”的数据报服务

    Socket类的常用构造器

    • public Socket(InetAddress address,int port)创建一个流套接字并将其连接到指定 IP 地址的指定端口号。
    • public Socket(String host,int port)创建一个流套接字并将其连接到指定主机上的指定端口号。

     Socket类的常用方法

    • public InputStream getInputStream()返回此套接字的输入流。可以用于接收网络消息
    • public OutputStream getOutputStream()返回此套接字的输出流。可以用于发送网络消息
    • public InetAddress getInetAddress()此套接字连接到的远程 IP 地址;如果套接字是未连接的,则返回 null。
    • public InetAddress getLocalAddress()获取套接字绑定的本地地址。 即本端的IP地址
    • public int getPort()此套接字连接到的远程端口号;如果尚未连接套接字,则返回 0。
    • public int getLocalPort()返回此套接字绑定到的本地端口。 如果尚未绑定套接字,则返回 -1。即本端的 端口号。
    • public void close()关闭此套接字。套接字被关闭后,便不可在以后的网络连接中使用(即无法重新连接 或重新绑定)。需要创建新的套接字对象。 关闭此套接字也将会关闭该套接字的 InputStream 和 OutputStream。
    • public void shutdownInput()如果在套接字上调用 shutdownInput() 后从套接字输入流读取内容,则流将 返回 EOF(文件结束符)。 即不能在从此套接字的输入流中接收任何数据。
    • public void shutdownOutput()禁用此套接字的输出流。对于 TCP 套接字,任何以前写入的数据都将被发 送,并且后跟 TCP 的正常连接终止序列。 如果在套接字上调用 shutdownOutput() 后写入套接字输出流, 则该流将抛出 IOException。 即不能通过此套接字的输出流发送任何数据。 

    TCP协议

    • 传输控制协议 (Transmission Control Protocol)
    • 使用TCP协议前,须先建立TCP连接,形成传输数据通道
    • 传输前,采用“三次握手”方式,点对点通信,是可靠的
    • TCP协议进行通信的两个应用进程:客户端、服务端。
    • 在连接中可进行大数据量的传输
    • 传输完毕,需释放已建立的连接,效率低(四次挥手)

    三次握手

    四次挥手

    基于Socket的TCP编程_客户端Socket的工作过程

    • 创建 Socket:根据指定服务端的 IP 地址或端口号构造 Socket 类对象。若服务器端 响应,则建立客户端到服务器的通信线路。若连接失败,会出现异常。

    • 打开连接到 Socket 的输入/出流: 使用 getInputStream()方法获得输入流,使用 getOutputStream()方法获得输出流,进行数据传输

    • 按照一定的协议对 Socket 进行读/写操作:通过输入流读取服务器放入线路的信息 (但不能读取自己放入线路的信息),通过输出流将信息写入线程。

    • 关闭 Socket:断开客户端到服务器的连接,释放线路 

      1. //从客户端发送文件给服务端,服务端保存到本地。并返回“发送成功”给客户端。
      2. //客户端
      3. @Test
      4. public void client() {
      5. Socket socket = null;
      6. OutputStream os = null;
      7. FileInputStream fis = null;
      8. ByteArrayOutputStream baos = null;
      9. try {
      10. //1.1创建Socket对象,指明服务器端的ip和端口号
      11. socket = new Socket(InetAddress.getByName("127.0.0.1"),7788);
      12. //1.2获取一个输出流,用于输出数据
      13. os = socket.getOutputStream();
      14. //1.3创建输入流,获取需要发送到服务端的文件
      15. fis = new FileInputStream(new File("E:\\JAVA\\java2\\src\\day9\\正能量.png"));
      16. //1.4将需要发送到服务端的文件读取到系统中
      17. byte[] bbuf = new byte[1024];
      18. int len;
      19. while ((len = fis.read(bbuf)) != -1){
      20. //1.5发送到服务端
      21. os.write(bbuf,0,len);
      22. }
      23. //1.6关闭数据的输出(否则服务端会一直等待接受,不会关闭)
      24. socket.shutdownOutput();
      25. //2.1获取一个输入流,用于输入服务端返回的”图片已收到”数据
      26. InputStream is = socket.getInputStream();
      27. //2.2实例化ByteArrayOutputStream对象,用以缓存接收到的服务端的数据
      28. baos = new ByteArrayOutputStream();
      29. //2.3将服务端返回的信息读入到系统
      30. byte[] bbuf1 = new byte[1024];
      31. int len1;
      32. while ((len1 = is.read(bbuf1)) != -1){
      33. //2.4将获取的数据缓存到ByteArrayOutputStream中,便于控制台输出
      34. baos.write(bbuf,0,len1);
      35. }
      36. System.out.println(baos.toString());
      37. } catch (IOException e) {
      38. e.printStackTrace();
      39. } finally {
      40. //3.资源的关闭
      41. try {
      42. if (fis != null)
      43. fis.close();
      44. } catch (IOException e) {
      45. e.printStackTrace();
      46. }
      47. try {
      48. if (os != null)
      49. os.close();
      50. } catch (IOException e) {
      51. e.printStackTrace();
      52. }
      53. try {
      54. if (socket != null)
      55. socket.close();
      56. } catch (IOException e) {
      57. e.printStackTrace();
      58. }
      59. try {
      60. if (baos != null)
      61. baos.close();
      62. } catch (IOException e) {
      63. e.printStackTrace();
      64. }
      65. }
      66. }

    基于Socket的TCP编程_服务器程序的工作过程

    • 调用 ServerSocket(int port) :创建一个服务器端套接字,并绑定到指定端口 上。用于监听客户端的请求。
    • 调用 accept():监听连接请求,如果客户端请求连接,则接受连接,返回通信 套接字对象。
    • 调用 该Socket类对象的 getOutputStream() 和 getInputStream ():获取输出 流和输入流,开始网络数据的发送和接收。
    • 关闭ServerSocket和Socket对象:客户端访问结束,关闭通信套接字。 
      1. //从客户端发送文件给服务端,服务端保存到本地。并返回“发送成功”给客户端。
      2. //服务端
      3. @Test
      4. public void server() {
      5. ServerSocket ss = null;
      6. Socket socket = null;
      7. InputStream is = null;
      8. FileOutputStream fos = null;
      9. OutputStream os = null;
      10. try {
      11. //1.1创建服务器端的ServerSocket,指明自己的端口号
      12. ss = new ServerSocket(7788);
      13. //1.2调用accept()表示接收来自于客户端的socket
      14. socket = ss.accept();
      15. //1.3获取一个输入流,用于接收客户端发送的数据
      16. is = socket.getInputStream();
      17. //1.4获取一个输出流,将接收到的客户端文件保存到本地
      18. fos = new FileOutputStream(new File("E:\\JAVA\\java2\\src\\day9\\正能量1.png"));
      19. //1.5获取客户端发送的文件操作
      20. byte[] bbuf = new byte[1024];
      21. int len;
      22. while ((len = is.read(bbuf)) != -1){
      23. //1.6将获取的客户端文件保存到本地的操作
      24. fos.write(bbuf,0,len);
      25. }
      26. System.out.println("图片保存成功");
      27. //2.1获取输出流,向客户端发送接收成功的信息
      28. os = socket.getOutputStream();
      29. os.write("图片已收到!".getBytes());
      30. } catch (IOException e) {
      31. e.printStackTrace();
      32. } finally {
      33. //3.资源关闭
      34. if (fos != null) {
      35. try {
      36. fos.close();
      37. } catch (IOException e) {
      38. e.printStackTrace();
      39. }
      40. }
      41. if (is != null) {
      42. try {
      43. is.close();
      44. } catch (IOException e) {
      45. e.printStackTrace();
      46. }
      47. }
      48. if (socket != null) {
      49. try {
      50. socket.close();
      51. } catch (IOException e) {
      52. e.printStackTrace();
      53. }
      54. }
      55. if (ss != null) {
      56. try {
      57. ss.close();
      58. } catch (IOException e) {
      59. e.printStackTrace();
      60. }
      61. }
      62. if (os != null) {
      63. try {
      64. os.close();
      65. } catch (IOException e) {
      66. e.printStackTrace();
      67. }
      68. }
      69. }
      70. }

    UDP协议 

    • 用户数据报协议(User Datagram Protocol) 
    • 将数据、源、目的封装成数据包,不需要建立连接
    • 每个数据报的大小限制在64K内
    • 发送不管对方是否准备好,接收方收到也不确认,故是不可靠的
    • 可以广播发送
    • 发送数据结束时无需释放资源,开销小,速度快 

    DatagramSocket 类的常用方法

    构造器:

    • public DatagramSocket(int port)创建数据报套接字并将其绑定到本地主机上的指定端口。套接字将被 绑定到通配符地址,IP 地址由内核来选择。
    • public DatagramSocket(int port,InetAddress laddr)创建数据报套接字,将其绑定到指定的本地地址。 本地端口必须在 0 到 65535 之间(包括两者)。如果 IP 地址为 0.0.0.0,套接字将被绑定到通配符地 址,IP 地址由内核选择。

    方法:

    • public void close()关闭此数据报套接字。
    • public void send(DatagramPacket p)从此套接字发送数据报包。DatagramPacket 包含的信息指示:将 要发送的数据、其长度、远程主机的 IP 地址和远程主机的端口号。
    • public void receive(DatagramPacket p)从此套接字接收数据报包。当此方法返回时,DatagramPacket 的缓冲区填充了接收的数据。数据报包也包含发送方的 IP 地址和发送方机器上的端口号。 此方法 在接收到数据报前一直阻塞。数据报包对象的 length 字段包含所接收信息的长度。如果信息比包的 长度长,该信息将被截短。
    • public InetAddress getLocalAddress()获取套接字绑定的本地地址。
    • public int getLocalPort()返回此套接字绑定的本地主机上的端口号。
    • public InetAddress getInetAddress()返回此套接字连接的地址。如果套接字未连接,则返回 null。
    • public int getPort()返回此套接字的端口。如果套接字未连接,则返回 -1。 

     DatagramPacket类常用方法

    构造器:

    • public DatagramPacket(byte[] buf,int length)构造 DatagramPacket,用来接收长 度为 length 的数据包。 length 参数必须小于等于 buf.length。
    • public DatagramPacket(byte[] buf,int length,InetAddress address,int port)构造数 据报包,用来将长度为 length 的包发送到指定主机上的指定端口号。length 参数必须小于等于 buf.length。

    方法:

    • public InetAddress getAddress()返回某台机器的 IP 地址,此数据报将要发往该 机器或者是从该机器接收到的。
    • public int getPort()返回某台远程主机的端口号,此数据报将要发往该主机或 者是从该主机接收到的。
    • public byte[] getData()返回数据缓冲区。接收到的或将要发送的数据从缓冲区 中的偏移量 offset 处开始,持续 length 长度。
    • public int getLength()返回将要发送或接收到的数据的长度。

    发送数据的步骤

    1. 创建发送端的Socket对象:(DatagramSocket)
    2. 创建数据, 并把数据打包:DatagramPacket(byteI] buf, int length, InetAddress address, int port)
    3. 调用DatagramSocket对象的方法发送数据:void send(DatagramPacket p)
    4. 关闭发送端:void close()
      1. @Test
      2. public void sender() throws Exception {
      3. //1.创建发送端的Socket对象
      4. DatagramSocket socket = new DatagramSocket();
      5. //2.创建数据
      6. String str = "UDP发送方式";
      7. byte[] data = str.getBytes();
      8. //3.打包数据
      9. InetAddress inetAddress = InetAddress.getLocalHost();
      10. DatagramPacket dp = new DatagramPacket(data,0,data.length,inetAddress,6677);
      11. //4.发送数据
      12. socket.send(dp);
      13. //5.关闭发送端
      14. socket.close();
      15. }

    接收数据的步骤

    1. 创建接收端的Socket对象:(DatagramSocket)、DatagramSocket(int port)
    2. 创建一个数据包, 用于接收数据:DatagramPacket(byte[] buf, int length)
    3. 调用DatagramSocke对象的方法接收数据:void receive(DatagramPacketp)
    4. 解析数据包, 并把数据在控制台显示:byte[] getData()、int getLength()
    5. 关闭接收端:void close()
      1. @Test
      2. public void receiver() throws Exception {
      3. //1.创建接收端的Socket对象
      4. DatagramSocket socket = new DatagramSocket(6677);
      5. //2.创建一个数据包, 用于接收数据
      6. byte[] bbuf = new byte[100];
      7. DatagramPacket dp = new DatagramPacket(bbuf,0,bbuf.length);
      8. //3.接收数据
      9. socket.receive(dp);
      10. //4.解析数据包, 并把数据在控制台显示
      11. String s = new String(dp.getData(),0,dp.getLength());
      12. System.out.println(s);
      13. //5.关闭接收端
      14. socket.close();
      15. }

    URL编程

    • URL(Uniform Resource Locator):统一资源定位符,它表示 Internet 上某一 资源的地址。
    • 它是一种具体的URI,即URL可以用来标识一个资源,而且还指明了如何locate 这个资源。
    • URL的基本结构由5部分组成:<传输协议>://<主机名>:<端口号>/<文件名>#片段名?参数列表参数列表格式:参数名=参数值&参数名=参数值....

    URL常用的构造器

    • public URL (String spec):通过一个表示URL地址的字符串可以构造一个URL对象。 如:URL url = new URL ("http://www. baidu.com/"); 
    • public URL(URL context, String spec):通过基 URL 和相对 URL 构造一个 URL 对象。 例如:URL downloadUrl = new URL(url, “download.html");
    • public URL(String protocol, String host, String file); 例如:new URL("http", "www.baidu.com", “download. html");
    • public URL(String protocol, String host, int port, String file); 例如: URL gamelan = new URL("http", "www.baidu.com", 80, “download.html");

    URL类的构造器都声明抛出非运行时异常,必须要对这一异常进行处理,通 常是用 try-catch 语句进行捕获。

    URL常用方法

    • public String getProtocol( ) 获取该URL的协议名
    • public String getHost( ) 获取该URL的主机名
    • public String getPort( ) 获取该URL的端口号
    • public String getPath( ) 获取该URL的文件路径
    • public String getFile( ) 获取该URL的文件名
    • public String getQuery( ) 获取该URL的查询名 

     HTTP协议的URLConnection类

    • URL的方法 openStream():能从网络上读取数据
    • 若希望输出数据,例如向服务器端的 CGI (公共网关接口-Common Gateway Interface-的简称,是用户浏览器和服务器端的应用程序进行连接的接口)程序发送一 些数据,则必须先与URL建立连接,然后才能对其进行读写,此时需要使用 URLConnection 。
    • URLConnection:表示到URL所引用的远程对象的连接。当与一个URL建立连接时, 首先要在一个 URL 对象上通过方法 openConnection() 生成对应的 URLConnection 对象。如果连接过程失败,将产生IOException.(URL netchinaren = new URL ("http://www.baidu.com/index.shtml");          URLConnectonn u = netchinaren.openConnection( );
      1. @Test
      2. public void test() {
      3. HttpURLConnection urlConnection = null;
      4. InputStream is = null;
      5. FileOutputStream fos = null;
      6. try {
      7. URL url = new URL("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fbpic.wotucdn.com%2Fpreview%2F00%2F00%2F78%2F99%2Fwater_789987_845f9a70e8d7eab08214.jpg%21%2Ffw%2F456%2Fquality%2F91%2Funsharp%2Ftrue%2Fcompress%2Ftrue%2Fcanvas%2F456x684a0a0%2Fformat%2Fjpeg&refer=http%3A%2F%2Fbpic.wotucdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1664962248&t=9eba95cc91dc491144c3911db4470c5f");
      8. urlConnection = (HttpURLConnection) url.openConnection();
      9. urlConnection.connect();
      10. is = urlConnection.getInputStream();
      11. fos = new FileOutputStream("E:\\JAVA\\java2\\src\\day9\\save.png");
      12. byte[] bbuf = new byte[1024];
      13. int len;
      14. while ((len = is.read(bbuf)) != -1){
      15. fos.write(bbuf,0,len);
      16. }
      17. System.out.println("下载完成");
      18. } catch (IOException e) {
      19. e.printStackTrace();
      20. } finally {
      21. try {
      22. if (fos != null)
      23. fos.close();
      24. } catch (IOException e) {
      25. e.printStackTrace();
      26. }
      27. try {
      28. if (is != null)
      29. is.close();
      30. } catch (IOException e) {
      31. e.printStackTrace();
      32. }
      33. if (urlConnection != null)
      34. urlConnection.disconnect();
      35. }
      36. }

    URI、URL和URN的区别 

    • URI,是uniform resource identifier,统一资源标识符,用来唯一的标识一个资源 
    • 而URL是uniform resource locator,统一资源定位符,它是一种具体 的URI,即URL可以用来标识一个资源,而且还指明了如何locate这个资源。
    • 而URN,uniform resource name,统一资源命名,是通过名字来标识资源, 比如mailto:java-net@java.sun.com。
    • 总的来说:URI是以一种抽象的,高层 次概念定义统一资源标识,而URL和URN则是具体的资源标识的方式。URL 和URN都是一种URI。
    • 在Java的URI中,一个URI实例可以代表绝对的,也可以是相对的,只要它符 合URI的语法规则。而URL类则 不仅符合语义,还包含了定位该资源的信息, 因此它不能是相对的。
  • 相关阅读:
    分布式事务详解
    Mac电脑交互式原型设计 Axure RP 8汉化最新 for mac
    java连接kubernete
    axios的安装使用
    协议栈——连接服务器
    Python多进程(process)(二)进程间通讯
    Revit相关插件如何实现【风管分割】功能?
    随想:卖包子送了杯豆浆
    简单工厂模式
    反转链表问题的递归解法
  • 原文地址:https://blog.csdn.net/m0_58052874/article/details/126627689