Java网络编程

网络编程

网络通信的要素

  • 网络编程中的两个主要问题:

    1. 如何准确定位到网络上的一台或多台主机

    2. 找到主机后如何进行通信

  • 网络编程中的要素:

    1. IP和端口号

    2. 网络通信协议

IP

ip地址:InetAddress类

  • 127.0.0.1:本机

  • ipconfig:查询本地ip

  • ip地址分类:

    • ipv4 / ipv6

      • ipv6:128位,8个无符号整数

    • 公网(互联网) / 私网(局域网)

 1      public static void main(String[] args) {
 2          try {
 3              //getByName返回查询的主机地址
 4              InetAddress inetaddress1 = InetAddress.getByName("127.0.0.1");
 5              System.out.println(inetaddress1);// /127.0.0.1
 6              InetAddress inetaddress2 = InetAddress.getByName("www.baidu.com");
 7              System.out.println(inetaddress2);// www.baidu.com/14.215.177.38
 8  9              //getLocalHost返回本机名称+地址
10              InetAddress inetaddress3 = InetAddress.getLocalHost();
11              System.out.println(inetaddress3);// Colins-LenovoR720/192.168.226.1
12              
13          } catch (UnknownHostException e) {
14              e.printStackTrace();
15          }
16      }

 

 

端口

端口表示计算机上一个程序的进程

  • 不同的进程端口号不同

  • 端口号:0-65535,

  • 端口分为TCP端口和UDP端口,所以实际端口数量=65536*2,但单个协议下端口号不能冲突

  • 端口分类:

    • 公有端口:0-1023

      • http:80

      • https:443

      • ftp:21

      • Telent:23

    • 程序注册端口:1024-49151

      • Tomcat:8080

      • MYSQL:3306

      • Oracle:1521

    • 动态 / 私有端口:49152-65535

1  netstat -ano #cmd查看所有端口
2  netstat -ano|findstr "端口号" #查看指定端口
3  tasklist|findstr "端口号" #查看指定端口的进程

 

ip地址+端口:InetSocketAddress类

1      public static void main(String[] args) {
2          //创建InetSocketAddress对象,对象包含ip和端口号
3          InetSocketAddress socketAddress = new InetSocketAddress("127.0.0.1",8080);
4          System.out.println(socketAddress);// /127.0.0.1:8080
5      }

 

 

通信协议

协议:约定

  • 网络通信协议:TCP/IP协议簇

    • TCP:用户传输协议:面向连接,客户端-服务端,三次握手/四次握手,效率低

    • UDP:用户数据报:无连接,没有明确的客户/服务端界限,DDOS

    • IP:网络互连协议

 

TCP

实现客户端和服务端通信

客户端

  1. 连接服务器Socket

  2. 发送消息

服务器

  1. 建立服务器端口 ServerSocket

  2. 等待用户的连接 accept

  3. 接收用户消息

消息发送

  1  //客户端
  2  public class TcpClientDemo01 {
  3      public static void main(String[] args) {
  4          //提升作用域,以便在finally中关闭
  5          Socket socket = null;
  6          OutputStream os = null;
  7          try {
  8              //1.获取服务器的地址
  9              InetAddress serverip = InetAddress.getByName("127.0.0.1");
 10              //2.获取端口号
 11              int port = 9999;
 12              //3.创建一个socket连接
 13              socket = new Socket(serverip,port);
 14              //4.发送消息 IO流
 15              os = socket.getOutputStream();
 16              os.write("Hi!".getBytes());
 17          } catch (Exception e) {
 18              e.printStackTrace();
 19          } finally {
 20              //关闭资源
 21              if (os != null) {
 22                  try {
 23                      os.close();
 24                  } catch (IOException e) {
 25                      e.printStackTrace();
 26                  }
 27              }
 28              if (socket != null) {
 29                  try {
 30                      socket.close();
 31                  } catch (IOException e) {
 32                      e.printStackTrace();
 33                  }
 34              }
 35          }
 36      }
 37  }
 38  39  //服务端
 40  public class TcpServerDemo01 {
 41      public static void main(String[] args) {
 42          //要实现在finally中关闭资源必须将作用域提升至try以外
 43          ServerSocket serverSocket = null;
 44          Socket socket = null;
 45          InputStream is = null;
 46          ByteArrayOutputStream baos = null;
 47          try {
 48  49              //1.ServerSocket创建服务器的地址---Socket->插座
 50              serverSocket = new ServerSocket(9999);
 51  52              while (true) {
 53                  //2.监听客户端连接(while true表示持续监听客户端)
 54                  socket = serverSocket.accept(); //阻塞式监听,会一直等待客户端连接
 55                  //3.读取客户端消息
 56                  is = socket.getInputStream();
 57                  //管道流接收(通过管道连接服务器和客户端的输入输出)
 58                  baos = new ByteArrayOutputStream();
 59                  byte[] buffer = new byte[1024];
 60                  int len;
 61                  while ((len=is.read(buffer))!=-1){
 62                      baos.write(buffer,0,len);
 63                  }
 64                  System.out.println(baos.toString());
 65              }
 66  67  68          } catch (IOException e) {
 69              e.printStackTrace();
 70          } finally {
 71              //关闭资源
 72              if (baos != null) {
 73                  try {
 74                      baos.close();
 75                  } catch (IOException e) {
 76                      e.printStackTrace();
 77                  }
 78              }
 79              if (is != null) {
 80                  try {
 81                      is.close();
 82                  } catch (IOException e) {
 83                      e.printStackTrace();
 84                  }
 85              }
 86              if (socket != null) {
 87                  try {
 88                      socket.close();
 89                  } catch (IOException e) {
 90                      e.printStackTrace();
 91                  }
 92              }
 93              if (serverSocket != null) {
 94                  try {
 95                      serverSocket.close();
 96                  } catch (IOException e) {
 97                      e.printStackTrace();
 98                  }
 99              }
100          }
101      }
102  }

 

文件传输

 

Tomcat

服务器

  • Tomcat服务器

客户端

  • 浏览器

 

启动Tomcat:bin目录 –> start.bat –> 浏览器访问localhost:8080

 

UDP

无连接,不需要知道对方的地址

没有明确区分服务器和客户机

消息发送

 1  //UDP发送端
 2  public class UdpClientDemo01 {
 3      public static void main(String[] args) throws Exception {
 4          //1.建立Socket
 5          DatagramSocket socket = new DatagramSocket();
 6          //这里也可以作为服务器端接收,UDP没有明确的服务器和客户机
 7          //DatagramSocket socket = new DatagramSocket(8080);
 8  9          //2.建包
10          String msg = "Hi UDP";
11          //建立发送对象
12          InetAddress localhost = InetAddress.getByName("localhost");
13          int port = 9090;
14          //DatagramPacket(数据,数据起始位置,数据长度,数据接收方ip+端口)
15          DatagramPacket packet = new DatagramPacket(msg.getBytes(), 0, msg.getBytes().length, localhost, port);
16 17          //3.发送包
18          socket.send(packet);
19 20          //4.关闭流
21          socket.close();
22      }
23  }
24 25  //UDP接收端
26  public class UdpServerDemo01 {
27      public static void main(String[] args) throws Exception{
28          //1.开放端口
29          DatagramSocket socket = new DatagramSocket(9090);
30 31          //2.接收数据包
32          byte[] buffer = new byte[1024];
33          DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);
34          //阻塞接收
35          socket.receive(packet);
36          System.out.println(packet.getAddress().getHostAddress());//输出客户端地址
37          //System.out.println(packet.getData());
38          System.out.println(new String(packet.getData(),0,packet.getLength()));
39          //3.关闭流
40          socket.close();
41      }
42  }

 

 

聊天

 1  public class UdpSenderDemo01 {
 2      public static void main(String[] args) throws Exception{
 3          DatagramSocket socket = new DatagramSocket(8888);
 4  5          //准备数据,控制台读取 System.in
 6          BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
 7  8          while (true){
 9              String data = reader.readLine();
10              byte[] datas = data.getBytes();
11              DatagramPacket packet = new DatagramPacket(datas,0,datas.length,new InetSocketAddress("localhost",6666));
12              socket.send(packet);
13              if (data.equals("close")){
14                  break;
15              }
16          }
17          socket.close();
18      }
19  }
20 21 22  public class UdpReceiverDemo01 {
23      public static void main(String[] args) throws Exception{
24          DatagramSocket socket = new DatagramSocket(6666);
25 26          BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
27 28          while (true){
29              //准备接收包裹
30              byte[] container = new byte[1024];
31              DatagramPacket packet = new DatagramPacket(container, 0, container.length);
32              socket.receive(packet); //阻塞式接收包裹
33 34              //读出接收的数据,设置连接断开条件
35              byte[] data = packet.getData();
36  //            String receiveData = new String(data, 0, data.length);
37              String receiveData = new String(data, 0, packet.getLength());
38              System.out.println(receiveData);
39              if (receiveData.trim().equals("close")){
40                  break;  //这里无法退出?以上receiveData用原本的方法会在结尾带有很多空格
41              }           //改为trim或packet.getlength()即可正常退出
42          }
43          socket.close();
44      }
45  }

 

 

 

posted @ 2021-03-11 00:50  Colin13  阅读(39)  评论(0编辑  收藏  举报