网络编程的目的、网路编程的两个主要问题:1. 定位主机以及主机上的特定应用(解决办法:socket(即IP:Port)、2. 可靠传输 (解决办法:网络通信协议,如TCP/IP)

image.png

image.png

通信要素1: Socket(IP:Port) 。 IP对应InetAddress对象、socket对应Socket(InetAddress实例,port)对象、ServerSocket(port) 。

注1: InetAddress.getByName()等来实例化,因其构造器不被外部访问。
注2:Socker和ServerSocket配套了相关IO流

image.png
image.png

(代码)InetAddress类

  1. package xj.java;
  2. import org.junit.jupiter.api.Test;
  3. import java.net.InetAddress;
  4. import java.net.UnknownHostException;
  5. /**
  6. * @author jia
  7. * @create 2021-12-02 1:33 下午
  8. */
  9. public class SocketTest {
  10. @Test
  11. public void inetAddressTest(){
  12. /*测试 socket实例(ip:port)的创建 */
  13. try {
  14. InetAddress inet1 = InetAddress.getByName("14.215.177.38"); // ip地址
  15. InetAddress inet2 = InetAddress.getByName("www.baidu.com"); // 域名(通过dns服务器间接获取ip地址)
  16. InetAddress inet3 = InetAddress.getByName("127.0.0.1"); // // 本地回路地址 方式一
  17. InetAddress inet4 = InetAddress.getLocalHost(); // 本地回路地址 方式二
  18. //
  19. System.out.println(inet1); // /14.215.177.38
  20. System.out.println(inet2); // www.baidu.com/14.215.177.38
  21. System.out.println(inet3); // /127.0.0.1
  22. System.out.println(inet4); // MacBook-Pro-9.local/127.0.0.1
  23. //
  24. System.out.println(inet2.getHostName()); // www.baidu.com
  25. System.out.println(inet2.getHostAddress()); // 14.215.177.38
  26. } catch (UnknownHostException e) {
  27. e.printStackTrace();
  28. }
  29. }
  30. }

通信要素2: 网络协议,TCP/IP为例

image.png
image.png

TCP网络编程: InetAddress类、Socket类、ServerSocket类

/* 代码实现原理: 1。客户端会创建一个为了与对方连接的socket对象(根据对方的ip:port),会通过该socket发送连接请求,如果对方同意请求,那么会接收到该socket。 2。服务器端会创建一个new ServerSocket(service_port)对象,并使用accept()方法即可监听该自身的端口,并且在接收客户端的连接请求后会拿到客户端的socket。 3。当客户端和服务器产生连接后,双方都拿到了socket对象。 此时,客户端可通过socket.getOutputStream()可拿到输出流以发送数据。 此时,服务器可通过socket.getInputStream()拿到输入流以接收数据。

  1. * 代码运行过程:
  2. * 1 先运行 service_socket() 来监听 客户端发来的请求连接。
  3. * 2 运行client_socket来拿到定位服务器的Socket
  4. * 3 之后便使用socket中提供的io流和本地的io来传输数据了。

(代码1 TCP : 客户端发送图片 + 服务器文字反馈)( 注意:文本特殊性,接收方要使用ByteArrayOutputStream流来接收字节数据)

  1. package xj.java;
  2. import org.junit.jupiter.api.Test;
  3. import java.io.*;
  4. import java.net.InetAddress;
  5. import java.net.ServerSocket;
  6. import java.net.Socket;
  7. /**
  8. * @author jia
  9. * @create 2021-12-02 4:54 下午
  10. */
  11. /**
  12. * 实现原理:
  13. * 1。客户端会创建一个为了与对方连接的socket对象(根据对方的ip:port),会通过该socket发送连接请求,如果对方同意请求,那么会接收到该socket。
  14. * 2。服务器端会创建一个new ServerSocket(service_port)对象,并使用accept()方法即可监听该自身的端口,并且在接收客户端的连接请求后会拿到客户端的socket。
  15. * 3。当客户端和服务器产生连接后,双方都拿到了socket对象。
  16. * 此时,客户端可通过socket.getOutputStream()可拿到输出流以发送数据。
  17. * 此时,服务器可通过socket.getInputStream()拿到输入流以接收数据。
  18. *
  19. * * 代码运行过程:
  20. * * 1。 先运行 service_socket() 来监听 客户端发来的请求连接。
  21. * * 2。 运行client_socket来拿到定位服务器的Socket。
  22. * * 3。 之后便使用socket中提供的io流和本地的io来传输数据了。
  23. *
  24. * 注意:下面的测试,应该在try-catch-finally中完成,为了方便才使用throws
  25. */
  26. public class SocketTest2 {
  27. /*
  28. * TCP发送图片文件
  29. * socket.shutdownOutput(); // 发送完文件后,发送方一定要做!否者等待方不知道何时结束接受,将被阻塞。
  30. * */
  31. @Test
  32. public void client_socket() throws IOException {
  33. /*客户端,从硬盘读取文件,并向服务器端发送字节数据*/
  34. // des_ip 和 des_port 目的是为与对方连接而创建一个socket,用于定位服务器中特定应用的地址。
  35. String des_ip = "127.0.0.1";
  36. int des_port = 12345;
  37. // 定义一些缓冲区
  38. byte[] buf = new byte[10];
  39. int buf_len = 0;
  40. // 1 创建一个为了与对方连接的socket。
  41. Socket socket = new Socket(InetAddress.getByName(des_ip), des_port);
  42. // 2 从socket获得输出流\输入流
  43. OutputStream socket_os = socket.getOutputStream();
  44. InputStream socket_is = socket.getInputStream();
  45. // 3 发送一张图片给对方:从本地获得的字节数据并发送给对方
  46. InputStream pic_bis = new BufferedInputStream(new FileInputStream("client_pic.png"));
  47. while ((buf_len = pic_bis.read(buf)) != -1) { // 将本地数据保存到缓冲区buf
  48. socket_os.write(buf, 0, buf_len); // 将buf中的数据发送给对方。
  49. }
  50. socket.shutdownOutput();
  51. // 4 接受服务区的反馈文字,并打印
  52. OutputStream word_baos = new ByteArrayOutputStream();
  53. buf = new byte[10];
  54. while ((buf_len = socket_is.read(buf)) != -1){
  55. //(注意: 不要直接打印buf中数据,会中文乱码,因为发送和接收时都采用固定大小的缓冲区发送字节数据。解决办法是:用数组接收全部数据)
  56. //System.out.println(buf.toString());
  57. word_baos.write(buf,0,buf_len);
  58. }
  59. System.out.println(word_baos.toString());
  60. socket.shutdownInput();
  61. // 5 关闭流和socket
  62. word_baos.close();
  63. pic_bis.close();
  64. socket.close();
  65. socket_is.close();
  66. socket_os.close();
  67. }
  68. @Test
  69. public void service_socket() throws IOException {
  70. /*服务器端,接收客户端发送的字节数据,并保存到硬盘*/
  71. int service_port = 12345;
  72. // 数据的缓冲区
  73. byte[] buf = new byte[10];
  74. int buf_len = 0;
  75. // 1 创建 server_socket服务器套接字(ip参数可忽略,因为是服务器自身的套接字) ,并监听对此套接字的连接请求并接受它。
  76. ServerSocket server_socket = new ServerSocket(service_port);
  77. Socket socket = server_socket.accept(); // 监听服务器自身的service_port端口,如果有客户端的连接请求就接收它。
  78. // 2 从socket获得输入流\输出流
  79. InputStream socket_is = socket.getInputStream();
  80. OutputStream socket_os = socket.getOutputStream();
  81. // 3.2 socket输入流中获得图片数据,并保存到本地。
  82. OutputStream pic_bos = new BufferedOutputStream(new FileOutputStream("server_pic.png"));
  83. while ((buf_len = socket_is.read(buf)) != -1) {
  84. pic_bos.write(buf, 0, buf_len);
  85. }
  86. socket.shutdownInput();
  87. // 4 给对方发送反馈文字
  88. socket_os.write("谢谢!我是服务器,我已经收到了你的图片".getBytes());
  89. socket.shutdownOutput();
  90. // 5 关闭流和socket
  91. pic_bos.close();
  92. socket_os.close();
  93. socket_is.close();
  94. socket.close();
  95. server_socket.close();
  96. }
  97. }

UDP网络编程: DatagramSocket类

image.png

代码

image.png
image.png

URL编程:

比如,下载软件中的“种子,这个种子就是url。image.png

  • 片段名:锚点。

    实例化、常用方法

    image.png

  • url查询名即参数列表

代码

核心思路:从tomcat服务器中,拿到目标资源的输入流 HttpURLConnection.getInputStream()
image.png

补充:tomcat - mac 的安装、启动

思路:
tomcat的可执行程序和shell文件都在bin目录下,比如bin/startup.sh来启动tomcat,访问http://localhost:8080/ 即可。

注1:如下,https://tomcat.apache.org/ 去下载安装包

image.png

注: 遇到文件权限问题,使用chmod 777命令来解决。比如, chmod 777 ~/Library/apache-tomcat/bin/*.sh