027-day26-网络

day26授课目录:

26.01_网络编程(网络编程概述)(了解)

  • A:计算机网络
  • 是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统。
  • B:网络编程
  • 就是用来实现网络互连的不同计算机上运行的程序间可以进行数据交换。

26.02_网络编程(网络编程三要素之IP概述)(掌握)

  • 每个设备在网络中的唯一标识
  • 每台网络终端在网络中都有一个独立的地址,我们在网络中传输数据就是使用这个地址。
  • ipconfig:查看本机IP192.168.12.42
  • ping:测试连接192.168.40.62
  • 本地回路地址:127.0.0.1 255.255.255.255是广播地址
  • IPv4:4个字节组成,4个0-255。大概42亿,30亿都在北美,亚洲4亿。2011年初已经用尽。
  • IPv6:8组,每组4个16进制数。
  • 1a2b:0000:aaaa:0000:0000:0000:aabb:1f2f
  • 1a2b::aaaa:0000:0000:0000:aabb:1f2f
  • 1a2b:0000:aaaa::aabb:1f2f
  • 1a2b:0000:aaaa::0000:aabb:1f2f
  • 1a2b:0000:aaaa:0000::aabb:1f2f

26.03_网络编程(网络编程三要素之端口号概述)(掌握)

  • 每个程序在设备上的唯一标识
  • 每个网络程序都需要绑定一个端口号,传输数据的时候除了确定发到哪台机器上,还要明确发到哪个程序。
  • 端口号范围从0-65535
  • 编写网络应用就需要绑定一个端口号,尽量使用1024以上的,1024以下的基本上都被系统程序占用了。
  • 常用端口
  • mysql: 3306
    • oracle: 1521
    • web: 80
    • tomcat: 8080
    • QQ: 4000
    • feiQ: 2425

26.04_网络编程(网络编程三要素协议)(掌握)

  • 为计算机网络中进行数据交换而建立的规则、标准或约定的集合。
  • UDP
  • 面向无连接,数据不安全,速度快。不区分客户端与服务端。
  • TCP
  • 面向连接(三次握手),数据安全,速度略低。分为客户端和服务端。
    • 三次握手: 客户端先向服务端发起请求, 服务端响应请求, 传输数据

26.05_网络编程(Socket通信原理图解)(了解)

image.png

  • A:Socket套接字概述:
  • 网络上具有唯一标识的IP地址和端口号组合在一起才能构成唯一能识别的标识符套接字。
    • 通信的两端都有Socket。
    • 网络通信其实就是Socket间的通信。
    • 数据在两个Socket间通过IO流传输。
    • Socket在应用程序中创建,通过一种绑定机制与驱动程序建立关系,告诉自己所对应的IP和port。

26.06_网络编程(UDP传输)(了解)

  • 1.发送Send

  • 创建DatagramSocket, 随机端口号

    • 创建DatagramPacket, 指定数据, 长度, 地址, 端口

    • 使用DatagramSocket发送DatagramPacket

    • 关闭DatagramSocket

      ```java package com.heima.socket;

      import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.SocketException; import java.net.UnknownHostException;

      public class Demo1_Send {

       1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      11
      12
      13
      14
      15
      16
      17
      /**
       * * 1.发送Send
       * 创建DatagramSocket, 随机端口号
       * 创建DatagramPacket, 指定数据, 长度, 地址, 端口
       * 使用DatagramSocket发送DatagramPacket
       * 关闭DatagramSocket
       * @throws SocketException 
       * @throws UnknownHostException 
       */
      public static void main(String[] args) throws Exception {
          String str = "what are you 弄啥呢?";
          DatagramSocket socket = new DatagramSocket();               //创建Socket相当于创建码头
          DatagramPacket packet =                                     //创建Packet相当于集装箱
                  new DatagramPacket(str.getBytes(), str.getBytes().length, InetAddress.getByName("127.0.0.1"), 6666); //字节,字节长度,地址,端口 
          socket.send(packet);                                        //发货,将数据发出去
          socket.close();                                             //关闭码头
      }
      

      }

      ```

  • 2.接收Receive

  • 创建DatagramSocket, 指定端口号

    • 创建DatagramPacket, 指定数组, 长度
    • 使用DatagramSocket接收DatagramPacket
    • 关闭DatagramSocket
    • 从DatagramPacket中获取数据
  • 3.接收方获取ip和端口号

  • String ip = packet.getAddress().getHostAddress();

    • int port = packet.getPort();

    ```java package com.heima.socket;

    import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.SocketException;

    public class Demo1_Receive {

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    /**
     ** 2.接收Receive
     * 创建DatagramSocket, 指定端口号
     * 创建DatagramPacket, 指定数组, 长度
     * 使用DatagramSocket接收DatagramPacket
     * 关闭DatagramSocket
     * 从DatagramPacket中获取数据
     * @throws Exception 
     */
    public static void main(String[] args) throws Exception {
        DatagramSocket socket = new DatagramSocket(6666);       //创建Socket相当于创建码头
        DatagramPacket packet = new DatagramPacket(new byte[1024], 1024);//创建Packet相当于创建集装箱,用来存接收到的数据,这里就不用了指定地址跟端口号了
        socket.receive(packet);                                 //接货,接收数据
    
        byte[] arr = packet.getData();                          //获取数据
        int len = packet.getLength();                           //获取有效的字节个数
        System.out.println(new String(arr,0,len));
        socket.close();
    }
    

    }

    ```

26.07_网络编程(UDP传输优化)

  • 接收端Receive

    ```java package com.heima.socket;

    import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.SocketException;

    public class Demo2_Receive {

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    /**
     ** 2.接收Receive
     * 创建DatagramSocket, 指定端口号
     * 创建DatagramPacket, 指定数组, 长度
     * 使用DatagramSocket接收DatagramPacket
     * 关闭DatagramSocket
     * 从DatagramPacket中获取数据
     * @throws Exception 
     */
    public static void main(String[] args) throws Exception {
        DatagramSocket socket = new DatagramSocket(6666);       //创建Socket相当于创建码头
        DatagramPacket packet = new DatagramPacket(new byte[1024], 1024);//创建Packet相当于创建集装箱
    
        while(true) {
            socket.receive(packet);                                 //接货,接收数据
    
            byte[] arr = packet.getData();                          //获取数据
            int len = packet.getLength();                           //获取有效的字节个数
            String ip = packet.getAddress().getHostAddress();       //获取ip地址
            int port = packet.getPort();                            //获取端口号
            System.out.println(ip + ":" + port + ":" + new String(arr,0,len));
        }
    }
    

    }

    ```

  • 发送端Send

    ```java package com.heima.socket;

    import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.SocketException; import java.net.UnknownHostException; import java.util.Scanner;

    public class Demo2_Send {

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    /**
     * * 1.发送Send 创建DatagramSocket, 随机端口号 创建DatagramPacket, 指定数据, 长度, 地址, 端口
     * 使用DatagramSocket发送DatagramPacket 关闭DatagramSocket
     * 
     * @throws SocketException
     * @throws UnknownHostException
     */
    public static void main(String[] args) throws Exception {
        Scanner sc = new Scanner(System.in); // 创建键盘录入对象
        DatagramSocket socket = new DatagramSocket(); // 创建Socket相当于创建码头
    
        while (true) {
            String line = sc.nextLine(); // 获取键盘录入的字符串
            if ("quit".equals(line)) { // 判断终止键盘输入
                break;
            }
            DatagramPacket packet = // 创建Packet相当于集装箱
            new DatagramPacket(line.getBytes(), line.getBytes().length,
                    InetAddress.getByName("127.0.0.1"), 6666);
            socket.send(packet); // 发货,将数据发出去
        }
        socket.close(); // 关闭码头
    }
    

    }

    ```

    26.08_网络编程(UDP传输多线程)

  • A发送和接收在一个窗口完成

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
package com.heima.socket;

    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    import java.util.Scanner;

    public class Demo3_MoreThread {

        /**
     * @param args
         * @throws InterruptedException
         */
        public static void main(String[] args) throws InterruptedException {
            new Receive().start();
            Thread.sleep(1000);
            new Send().start();
        }

    }

    class Receive extends Thread {
        public void run() {
            try {
                DatagramSocket socket = new DatagramSocket(6666); // 创建Socket相当于创建码头
                DatagramPacket packet = new DatagramPacket(new byte[1024], 1024);// 创建Packet相当于创建集装箱

                while (true) {
                    socket.receive(packet); // 接货,接收数据

                byte[] arr = packet.getData(); // 获取数据
                    int len = packet.getLength(); // 获取有效的字节个数
                    String ip = packet.getAddress().getHostAddress(); // 获取ip地址
                    int port = packet.getPort(); // 获取端口号
                    System.out.println(ip + ":" + port + ":"
                            + new String(arr, 0, len));
                }
            } catch (IOException e) {

                e.printStackTrace();
            }
        }
    }

    class Send extends Thread {
        public void run() {
            try {
                Scanner sc = new Scanner(System.in); // 创建键盘录入对象
                DatagramSocket socket = new DatagramSocket(); // 创建Socket相当于创建码头

                while (true) {
                    String line = sc.nextLine(); // 获取键盘录入的字符串
                    if ("quit".equals(line)) {
                        break;
                    }
                    DatagramPacket packet = // 创建Packet相当于集装箱
                    new DatagramPacket(line.getBytes(), line.getBytes().length,
                            InetAddress.getByName("127.0.0.1"), 6666);
                    socket.send(packet); // 发货,将数据发出去
                }
                socket.close();
            } catch (IOException e) {

                e.printStackTrace();
            }
        }
    }


26.09_网络编程(UDP聊天图形化界面)

image.png

26.10_网络编程(UDP聊天发送功能)

26.11_网络编程(UDP聊天记录功能)

26.12_网络编程(UDP聊天清屏功能)

26.13_网络编程(UDP聊天震动功能)

26.14_网络编程(UDP聊天快捷键和代码优化)

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
package com.heima.socket;

import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Color;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Panel;
import java.awt.TextArea;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Demo4_GUIChat extends Frame {  //继承frame就可以直接使用frame的所有方法

    private TextField tf;
    private Button send;
    private Button log;
    private Button clear;
    private Button shake;
    private TextArea viewText;
    private TextArea sendText;
    private DatagramSocket socket;
    private BufferedWriter bw;
    /**
     * @param args
     * GUI聊天
     */
    public Demo4_GUIChat() {
        init();
        southPanel();
        centerPanel();
        event();
    }

    public void event() {
        this.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                try {
                    socket.close();
                    bw.close();
                } catch (IOException e1) {

                    e1.printStackTrace();
                }
                System.exit(0);
            }
        });

        send.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                try {
                    send();
                } catch (IOException e1) {

                    e1.printStackTrace();
                }
            }

        });

        log.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                try {
                    logFile();
                } catch (IOException e1) {

                    e1.printStackTrace();
                }
            }

        });

        clear.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                viewText.setText("");
            }
        });

        shake.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                try {
                    send(new byte[]{-1},tf.getText());
                } catch (IOException e1) {

                    e1.printStackTrace();
                }
            }

        });

        sendText.addKeyListener(new KeyAdapter() {
            @Override
            public void keyReleased(KeyEvent e) {
                //if(e.getKeyCode() == KeyEvent.VK_ENTER && e.isControlDown()) {    //isControlDown ctrl是否被按下
                if(e.getKeyCode() == KeyEvent.VK_ENTER) {
                    try {
                        send();
                    } catch (IOException e1) {

                        e1.printStackTrace();
                    }
                }
            }
        });
    }


    private void shake() {
        int x = this.getLocation().x;                           //获取横坐标位置
        int y = this.getLocation().y;                           //获取纵坐标位置

        for(int i = 0; i < 20; i++) {
            try {
                this.setLocation(x + 20, y + 20);
                Thread.sleep(20);
                this.setLocation(x + 20, y - 20);
                Thread.sleep(20);
                this.setLocation(x - 20, y + 20);
                Thread.sleep(20);
                this.setLocation(x - 20, y - 20);
                Thread.sleep(20);
                this.setLocation(x, y);
            } catch (InterruptedException e) {

                e.printStackTrace();
            }
        }
    }

    private void logFile() throws IOException {
        bw.flush();                                 //刷新缓冲区
        FileInputStream fis = new FileInputStream("config.txt");
        ByteArrayOutputStream baos = new ByteArrayOutputStream();   //在内存中创建缓冲区

        int len;
        byte[] arr = new byte[8192];
        while((len = fis.read(arr)) != -1) {
            baos.write(arr, 0, len);
        }

        String str = baos.toString();               //将内存中的内容转换成了字符串
        viewText.setText(str);

        fis.close();
    }

    private void send(byte[] arr, String ip) throws IOException {
        DatagramPacket packet = 
                new DatagramPacket(arr, arr.length, InetAddress.getByName(ip), 9999);
        socket.send(packet);                        //发送数据
    }

    private void send() throws IOException {
        String message = sendText.getText();        //获取发送区域的内容
        String ip = tf.getText();                   //获取ip地址;
        ip = ip.trim().length() == 0 ? "255.255.255.255" : ip;

        send(message.getBytes(),ip);

        String time = getCurrentTime();             //获取当前时间
        String str = time + " 我对:" + (ip.equals("255.255.255.255") ? "所有人" : ip) + "说\r\n" + message + "\r\n\r\n";  //alt + shift + l 抽取局部变量
        viewText.append(str);                       //将信息添加到显示区域中
        bw.write(str);                              //将信息写到数据库中
        sendText.setText("");


    }

    private String getCurrentTime() {
        Date d = new Date();                        //创建当前日期对象
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
        return sdf.format(d);                       //将时间格式化
    }

    public void centerPanel() {
        Panel center = new Panel();                 //创建中间的Panel
        viewText = new TextArea();
        sendText = new TextArea(5,1);
        center.setLayout(new BorderLayout());       //设置为边界布局管理器
        center.add(sendText,BorderLayout.SOUTH);    //发送的文本区域放在南边
        center.add(viewText,BorderLayout.CENTER);   //显示区域放在中间
        viewText.setEditable(false);                //设置不可以编辑
        viewText.setBackground(Color.WHITE);        //设置背景颜色
        sendText.setFont(new Font("xxx", Font.PLAIN, 15));
        viewText.setFont(new Font("xxx", Font.PLAIN, 15));
        this.add(center,BorderLayout.CENTER);
    }

    public void southPanel() {
        Panel south = new Panel();                  //创建南边的Panel
        tf = new TextField(15);
        tf.setText("127.0.0.1");
        send = new Button("发 送");
        log = new Button("记 录");
        clear = new Button("清 屏");
        shake = new Button("震 动");
        south.add(tf);
        south.add(send);
        south.add(log);
        south.add(clear);
        south.add(shake);
        this.add(south,BorderLayout.SOUTH);         //将Panel放在Frame的南边
    }

    public void init() {
        this.setLocation(500, 50);
        this.setSize(400, 600);
        new Receive().start();
        try {
            socket = new DatagramSocket();
            bw = new BufferedWriter(new FileWriter("config.txt",true)); //需要在尾部追加
        } catch (Exception e) {

            e.printStackTrace();
        }
        this.setVisible(true);
    }
    private class Receive extends Thread {          //接收和发送需要同时执行,所以定义成多线程的
        public void run() {
            try {
                DatagramSocket socket = new DatagramSocket(9999);
                DatagramPacket packet = new DatagramPacket(new byte[8192], 8192);

                while(true) {
                    socket.receive(packet);             //接收信息
                    byte[] arr = packet.getData();      //获取字节数据
                    int len = packet.getLength();       //获取有效的字节数据
                    if(arr[0] == -1 && len == 1) {      //如果发过来的数组第一个存储的值是-1,并且数组长度是1
                        shake();                        //调用震动方法
                        continue;                       //终止本次循环,继续下次循环,因为震动后不需要执行下面的代码
                    }
                    String message = new String(arr,0,len); //转换成字符串

                    String time = getCurrentTime();     //获取当前时间
                    String ip = packet.getAddress().getHostAddress();   //获取ip地址
                    String str = time + " " + ip + " 对我说:\r\n" + message + "\r\n\r\n";
                    viewText.append(str);
                    bw.write(str);
                }
            } catch (Exception e) {

                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        new Demo4_GUIChat();
    }

}

26.15_网络编程(UDP聊天生成jar文件)

26.16_网络编程(TCP协议)(掌握)

  • 1.客户端

  • 创建Socket连接服务端(指定ip地址,端口号)通过ip地址找对应的服务器

    • 调用Socket的getInputStream()和getOutputStream()方法获取和服务端相连的IO流
    • 输入流可以读取服务端输出流写出的数据
    • 输出流可以写出数据到服务端的输入流

    ```java package com.heima.tcp;

    import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import java.net.UnknownHostException;

    public class Demo1_Client {

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    /**
     * * 1.客户端 创建Socket连接服务端(指定ip地址,端口号)通过ip地址找对应的服务器
     * 调用Socket的getInputStream()和getOutputStream()方法获取和服务端相连的IO流
     * 输入流可以读取服务端输出流写出的数据 输出流可以写出数据到服务端的输入流
     * 
     * @throws IOException
     * @throws UnknownHostException
     */
    public static void main(String[] args) throws UnknownHostException,
            IOException {
        Socket socket = new Socket("127.0.0.1", 12345); // 服务器的ip地址及端口号
    
        InputStream is = socket.getInputStream(); // 获取服务端输入流
        OutputStream os = socket.getOutputStream(); // 获取客户端的输出流
    
        byte[] arr = new byte[1024];
        int len = is.read(arr); // 读取服务器发过来的数据
        System.out.println(new String(arr, 0, len)); // 将数据转换成字符串并打印
    
        os.write("学习挖掘机哪家强?".getBytes()); // 客户端向服务器写数据
    
        socket.close();
    }
    

    }

    ```

  • 2.服务端

  • 创建ServerSocket(需要指定端口号)

    • 调用ServerSocket的accept()方法接收一个客户端请求,得到一个Socket
    • 调用Socket的getInputStream()和getOutputStream()方法获取和客户端相连的IO流
    • 输入流可以读取客户端输出流写出的数据
    • 输出流可以写出数据到客户端的输入流

    ```java package com.heima.tcp;

    import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket;

    public class Demo1_Server {

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    /**
     * * 2.服务端 创建ServerSocket(需要指定端口号)
     * 调用ServerSocket的accept()方法接收一个客户端请求,得到一个Socket
     * 调用Socket的getInputStream()和getOutputStream()方法获取和客户端相连的IO流
     * 输入流可以读取客户端输出流写出的数据 输出流可以写出数据到客户端的输入流
     * 
     * @throws IOException
     */
    public static void main(String[] args) throws IOException {
        ServerSocket server = new ServerSocket(12345); // 创建一个服务端,端口号是12345
    
        Socket socket = server.accept(); // 接受客户端的请求
        InputStream is = socket.getInputStream(); // 获取客户端输入流
        OutputStream os = socket.getOutputStream(); // 获取服务端的输出流
    
        os.write("百度一下你就知道".getBytes()); // 服务器向客户端写出数据
    
        byte[] arr = new byte[1024];
        int len = is.read(arr); // 读取客户端发过来的数据
        System.out.println(new String(arr, 0, len)); // 将数据转换成字符串并打印
    
        socket.close();
    }
    

    }

    ```

26.17_网络编程(TCP协议代码优化)

  • 客户端

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
```java
Socket socket = new Socket("127.0.0.1", 9999);      //创建Socket指定ip地址和端口号
    InputStream is = socket.getInputStream();           //获取输入流
    OutputStream os = socket.getOutputStream();         //获取输出流
    BufferedReader br = new BufferedReader(new InputStreamReader(is));
    PrintStream ps = new PrintStream(os);
System.out.println(br.readLine());
ps.println("我想报名就业班");
System.out.println(br.readLine());
ps.println("爷不学了");
socket.close();
```
  • 服务端


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
```java
ServerSocket server = new ServerSocket(9999);   //创建服务器
    Socket socket = server.accept();                //接受客户端的请求
    InputStream is = socket.getInputStream();       //获取输入流
    OutputStream os = socket.getOutputStream();     //获取输出流
BufferedReader br = new BufferedReader(new InputStreamReader(is));
PrintStream ps = new PrintStream(os);

ps.println("欢迎咨询传智播客");
System.out.println(br.readLine());
ps.println("报满了,请报下一期吧");
System.out.println(br.readLine());
server.close();
socket.close();
```

26.18_网络编程(服务端是多线程的)(掌握)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
    ServerSocket server = new ServerSocket(9999);   //创建服务器
        while(true) {
            final Socket socket = server.accept();              //接受客户端的请求
            new Thread() {
                public void run() {
                    try {
                        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                        PrintStream ps = new PrintStream(socket.getOutputStream());
                        ps.println("欢迎咨询传智播客");
                        System.out.println(br.readLine());
                        ps.println("报满了,请报下一期吧");
                        System.out.println(br.readLine());
                        socket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }.start();
        }
    }

26.19_网络编程(练习)

  • 客户端向服务器写字符串(键盘录入),服务器(多线程)将字符串反转后写回,客户端再次读取到是反转后的字符串

    客户端

    ```java package com.heima.test;

    import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintStream; import java.net.Socket; import java.net.UnknownHostException; import java.util.Scanner;

    public class Test1_Client {

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    /**
     * 客户端向服务器写字符串(键盘录入),服务器(多线程)将字符串反转后写回,客户端再次读取到是反转后的字符串
     * @throws IOException 
     * @throws UnknownHostException 
     */
    public static void main(String[] args) throws UnknownHostException, IOException {
        Scanner sc = new Scanner(System.in);                //创建键盘录入对象
        Socket socket = new Socket("127.0.0.1", 54321);     //创建客户端,指定ip地址和端口号
    
        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); //获取输入流
        PrintStream ps = new PrintStream(socket.getOutputStream());//获取输出流
    
        ps.println(sc.nextLine());                          //将字符串写到服务器去
        System.out.println(br.readLine());                  //将反转后的结果读出来
    
        socket.close();
    }
    

    }

    ```

    服务端

    ```java package com.heima.test;

    import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintStream; import java.net.ServerSocket; import java.net.Socket;

    public class Test1_Server {

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    /**
     * @param args
     * @throws IOException 
     */
    public static void main(String[] args) throws IOException {
        ServerSocket server = new ServerSocket(54321);
        System.out.println("服务器启动,绑定54321端口");
    
        while(true) {
            final Socket socket = server.accept();                  //接受客户端的请求
    
            new Thread() {                                          //开启一条线程
                public void run() {
                    try {
                        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); //获取输入流
                        PrintStream ps = new PrintStream(socket.getOutputStream());//获取输出流
    
                        String line = br.readLine();                //将客户端写过来的数据读取出来
                        line = new StringBuilder(line).reverse().toString();    //链式编程
                        ps.println(line);                           //反转后写回去
    
                        socket.close();
                    } catch (IOException e) {
    
                        e.printStackTrace();
                    }
                }
            }.start();
        }
    }
    

    }

    ```

    26.20_网络编程(练习)

  • 客户端向服务器上传文件

    服务端

    ```java package com.heima.test;

    import java.io.BufferedReader; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.PrintStream; import java.net.ServerSocket; import java.net.Socket;

    public class Test2_UpdateServer {

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    /**
     * @param args
     * @throws IOException 
     */
    public static void main(String[] args) throws IOException {
        //3,建立多线程的服务器
        ServerSocket server = new ServerSocket(12345);
        System.out.println("服务器启动,绑定12345端口号");
    
        //4.读取文件名
        while(true) {
            final Socket socket = server.accept();                  //接受请求
            new Thread() {
                public void run() {
                    try {
                        InputStream is = socket.getInputStream();
                        BufferedReader br = new BufferedReader(new InputStreamReader(is));
                        PrintStream ps = new PrintStream(socket.getOutputStream());
                        String fileName = br.readLine();
    
                        //5.判断文件是否存在, 将结果发回客户端
                        File dir = new File("update");
                        dir.mkdir();                                //创建文件夹
                        File file = new File(dir,fileName);         //封装成File对象
    
                        if(file.exists()) {                         //如果服务器已经存在这个文件
                            ps.println("存在");                       //将存在写给客户端
                            socket.close();                         //关闭socket
                            return;
                        }else {
                            ps.println("不存在");
                        }
    
                        //8.定义FileOutputStream, 从网络读取数据, 存储到本地
                        FileOutputStream fos = new FileOutputStream(file);
                        byte[] arr = new byte[8192];
                        int len;
    
                        while((len = is.read(arr)) != -1) {
                            fos.write(arr, 0, len);
                        }
    
                        fos.close();
                        socket.close();
                    } catch (IOException e) {
    
                        e.printStackTrace();
                    }
                }
            }.start();
        }
    
    }
    

    }

    ```

    客户端

    ```java package com.heima.test;

    import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintStream; import java.net.Socket; import java.net.UnknownHostException; import java.util.Scanner;

    public class Test2_UpdateClient {

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    /**
     * @param args
     * @throws IOException 
     * @throws UnknownHostException 
     */
    public static void main(String[] args) throws UnknownHostException, IOException {
        // 1.提示输入要上传的文件路径, 验证路径是否存在以及是否是文件夹
        File file = getFile();
        // 2.发送文件名到服务端
        Socket socket = new Socket("127.0.0.1", 12345);
        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        PrintStream ps = new PrintStream(socket.getOutputStream());
        ps.println(file.getName());
        // 6.接收结果, 如果存在给予提示, 程序直接退出
        String result = br.readLine();                      //读取存在后不存在的结果
        if("存在".equals(result)) {
            System.out.println("您上传的文件已经存在,请不要重复上传");
            socket.close();
            return;
        }
        // 7.如果不存在, 定义FileInputStream读取文件, 写出到网络
        FileInputStream fis = new FileInputStream(file);
        byte[] arr = new byte[8192];
        int len;
    
        while((len = fis.read(arr)) != -1) {
            ps.write(arr, 0, len);
        }
    
        fis.close();
        socket.close();
    }
    
    private static File getFile() {
        Scanner sc = new Scanner(System.in);                //创建键盘录入对象
        System.out.println("请输入一个文件路径:");
    
        while(true) {
            String line = sc.nextLine();
            File file = new File(line);
    
            if(!file.exists()) {
                System.out.println("您录入的文件路径不存在,请重新录入:");
            }else if(file.isDirectory()) {
                System.out.println("您录入的是文件夹路径,请输入一个文件路径:");
            }else {
                return file;
            }
        }
    }
    

    }

    ```

    26.21_day26总结

  • 把今天的知识点总结一遍。