几个概念

互联网软件结构:

  • 客户端-服务器(Client/Server,C/S)架构:胖客户端架构,图形表现力强、安全性能简单、响应速度快,但无法跨平台、针对特定人群、维护成本高、一般采用TCP协议。
  • 浏览器-服务器(Browser/Server,B/S)架构:瘦客户端架构,使用方便、能够跨平台使用、针对大众人群、一般采用更上层次的协议(如HTTP、FTP等),但跨浏览器兼容性不好,在速度、安全性和表现力上需要花费更多时间。

网络协议与架构:

  • TCP/IP协议:即传输控制协议/因特网互联协议( Transmission Control Protocol/Internet Protocol),是互联网中最基本、使用最广泛的协议。IP协议定义了计算机如何连入互联网(即如何找到终端),TCP协议定义了数据如何在计算机之间进行传输(即网络连接的方式)。
  • 四层架构:TCP/IP协议栈采用4(5)层结构,分别是应用层、传输层、网络层、链路层、(物理层)。
  • UDP协议:即用户数据报协议(User Datagram Protocol)。数据的发送端和接收端不建立连接,也不能保证接收端能接收成功。通常用于音频、视频和普通数据的传输。
  • TCP协议:是面向连接的通信协议。发送端和接收端需要建立连接才能传输数据,是可靠的、无差错的数据传输协议。每次连接的创建都需要经过“三次握手”的过程。
  • IP协议:即互联网协议地址(Internet Protocol Address),作为一个网络中的计算机设备的唯一编号。
  • 端口号:由应用程序占用,能够定位设备上的一个应用程序。端口号的取值范围是0~65535。其中,0~1023之间的端口号用于系统内部的使用。查看端口的方式如下: ```shell // Windows中 netstat -aon | findstr 8888 #查看占用8888端口号的进程PID TCP 0.0.0.0:8888 0.0.0.0:0 LISTENING 2696 #显示结果,找到占用8888端口号的PID taskkill /F /pid 2696 #强制关闭

// Linux中 netstat -anp | grep :8888 #查看占用8888端口号的进程PID tcp 0 0 :::8888 :::* LISTEN 3626/java #显示结果,找到占用8888端口号的PID kill -9 3626 #强制关闭

  1. <a name="yuYfT"></a>
  2. ## TCP网络编程
  3. TCP协议需要严格区分客户端和服务器,需要由客户端发起请求,服务器响应后,建立连接。在Java中提供了客户端和服务端的抽象——类,用于编程。
  4. - 客户端的类:java.net.Socket
  5. - 服务端的类:java.net.ServerSocket
  6. 通过上面两个类进行的编程,又被称为套接字编程。
  7. ```java
  8. // 客户端
  9. Socket socket = new Socket("127.0.0.1", 8888); // 定义ip和端口
  10. OutputStream os = socket.getOutputStream();
  11. // 得到网络字节输出流,用包裹数据并发送到网络
  12. PrintWriter pw = new PrintWriter(os); // 用快速输出流包裹,方便按行输出
  13. pw.println("ABCBoy");
  14. pw.flush();
  15. // os.close(); 关闭网络流同时关闭网络
  16. socket.shutdownOutput(); // 只关闭网络流而不关闭socket
  17. socket.close(); // 关闭socket
  18. // 服务端
  19. ServerSocket ss = new ServerSocket(8888); // 定义端口
  20. Socket socket = ss.accept(); // 等待客户端发送数据
  21. // 一直处于waiting状态直到接收到数据
  22. /** 当客户端发送数据后,接着往下执行 **/
  23. InputStream stream = socket.getInputStream(); // 获取客户端发送的数据
  24. BufferedReader reader = new BufferedReader(
  25. new InputStreamReader(stream)); // 将字节流转换为字符流,同时使用缓冲流包裹
  26. String line = null;
  27. while((line = reader.readLine()) != null) {
  28. System.out.println(line); // 按行打印
  29. }
  30. reader.close(); // 关闭缓冲流,内部的全部流以及服务端都会被连带关闭

当客户端发送请求后,需要关闭发送流(shutdownOutput),服务器才能发送响应流到客户端,否则会出现死锁。或者,服务端关闭接收流也可以。
在实际应用中,客户端便是浏览器。浏览器访问服务器会发送一个固定格式的请求,而服务器也会发送一个固定格式的响应。详见HTTP

UDP网络编程

UDP协议没有发送端和接收端的区分,发送时也不需要建立连接。在Java中提供了一个UDP端的类:java.net.DatagramSocket,和一个UDP发送的数据包的类:java.net.DatagramPacket。

  1. DatagramSocket ds = new DatagramSocket(); // 构建发送端
  2. byte[] bs = "天青色等烟雨,小狗在等你".getBytes(); // 构建byte数组
  3. DatagramPacket packet = new DatagramPacket(bs, 0, bs.length,
  4. InetAddress.getByName("127.0.0.1"), 8888); // 构建数据包
  5. ds.send(packet); // 发送
  6. ds.close(); // 关闭发送端
  7. DatagramSocket ds = new DatagramSocket(8888); // 构建接收端
  8. byte[] buf = new byte[1024]; // 构建接收数组
  9. DatagramPacket packet = new DatagramPacket(buf, 0, buf.length);
  10. // 构建接收包,将接收到的数据存入buf数组中
  11. ds.receive(packet); // 开始/等待接收
  12. String string = new String(buf, 0, buf.length);
  13. // 接收到后获取buf数组并转成字符串
  14. System.out.println(string);
  15. ds.close();

URL和URI

统一资源标识符(Uniform Resource Identifier)是用来唯一的标识一个网络资源,而统一资源定位符(uniform resource locator)则是一种具体的URI,用来标识和定位某个资源。例如,http://127.0.0.1/hello即是一个URL,而/hello则是URI。
在Java中,可以通过java.net.URL类对象获取连接,模拟一个浏览器,获取网络资源返回的内容。

  1. URL url = new URL("https://www.jd.com");
  2. HttpURLConnection httpConn = (HttpURLConnection) url.openConnection(); // 获取连接
  3. httpConn.setRequestMethod("GET"); //设置请求方式
  4. httpConn.setRequestProperty("User-Agent", //模拟浏览器发送的请求
  5. "Mozilla/5.0 (Windows NT 10.0; Win64; x64;rv:79.0) Gecko/20100101 Firefox/79.0");
  6. InputStream is = httpConn.getInputStream(); //获取连接输入流