网络编程2019-08-21

目的:网络编程:在两台不同的计算机之间数据传递

服务器端与客户端的数据传输,单向传递,双向传递,终端接收数据传递等。

  • 上传与下载:
    客户端 1.文本 2.图片 3.音频 4.视频 服务器端、


    借鉴优秀的人的图片.jpg

技术:

知识点:
* 网络编程:在两台不同的计算机之间数据传递
 * 1.QQ聊天
 * 2.打开网易APP 刷新界面 就有数据
 * 3.打开浏览器 网页www.baidu.com
 *
 * 客户端:手机APP 浏览器 桌面QQ
 * 服务器端:存储/处理数据
 *
 * URL : 统一的资源定位
 *  http://www.baidu.com/search?code=android&type=1
 *  http/https: 传输协议   Tcp/IP 具体实现
 *  www.baidu.com :域名 表示一台网络中的电脑
 *        (ipv4、ipv6)ip地址 : 唯一标识一台网络中的电脑
 *         32位:四个部分每个8个字节
 *         192.168.43.117 <-> www.baidu.com
 *
 *         DNS服务器: 域名解析
 *        将www.baidu.com类型的域名解析为对应的Ip地址
 *
 *  search 对应的后台程序文件  php java jsp
 *  ? 表示运行这个程序需要传递的参数
 *  code=android :code是服务器段指定的字段
 *  & 如果有多个参数 使用&符号链接
 *
 *  ip地址唯一标识某一台电脑
 *  端口号:唯一标识电脑上的某一个进程(程序)80
 *
 *  数据传输:TCP/IP协议
 *  TCP : 面向链接的 安全  如打电话
 *  UTP : 面向不链接的 不安全 快  如古代飞鸽传书
 *
 * 网络中的数据传输:Socket实现 -> 套接字
 * Socket类: 客户端
 * ServerSocket服务器端
 *
 *   读取数据: 服务器端读取 客户端读取
 *            BufferReader -> InputStreamReader -> socket.getInputStream()
 *            从终端读取:
 *            BufferReader -> InputStreamReader -> System.in
 *   输出数据:客户端输出 服务器端输出
 *            BufferedWriter -> OutputStreamWriter -> socket.getOutputStream
 *            PrintStream -> socket.getOutputStream

实际编程:

(1).简单的服务器端与客户端数据传输;

定义客户端:
//模拟客户端
class Client{
    public static void main(String[] args) throws IOException {
        //1.创建用于通信的Socket
        //指明和谁通信:IP地址 端口号
        Socket socket = new Socket("192.168.43.117",8989);

        //接收服务器端的数据
        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String line = null;
        while ((line =  br.readLine()) != null){
            System.out.println(line);
        }


        //向服务器端发送数据
        //socket.getOutputStream();
        PrintStream ps = new PrintStream(socket.getOutputStream());
        ps.println("你好啊");

        //输出完毕
        socket.shutdownOutput();
    }
}
定义服务器端:
//模拟服务器端
class Server{
    public static void main(String[] args) throws IOException {
        //1.创建服务器端的serverSocket
        ServerSocket ss = new ServerSocket(8989);

        //2.获取链接的客户端的socket
        Socket clientSocket = ss.accept();

        //3.向客户端发送数据
        //BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
        PrintStream ps = new PrintStream(clientSocket.getOutputStream());
        ps.println("登录成功");

        //输出完毕
        clientSocket.shutdownOutput();

        //4.接收客户端发来的数据
        BufferedReader br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
        String line = null;
        while ((line = br.readLine()) != null){
            System.out.println(line);
        }
    }
}
调用时必须先运行服务器端再运行客户端。

(2)手动输入内容 发送

以上代码进行简单更改:
class MyClient{
    public static void main(String[] args){
        //连接服务器端的Socket
        Socket socket = null;
        try {
            socket = new Socket("192.168.43.117", 8888);

            //接收服务器信息
            BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            String line = null;
            while ((line = br.readLine()) != null){
                System.out.println(line);
            }

//            //从终端输出数据,发送给服务器端
//            //获取终端数据
//            BufferedReader keyin = new BufferedReader(new InputStreamReader(System.in));
//            //获取向客户端的输出数据的输出流
//            PrintStream ps = new PrintStream(socket.getOutputStream());
//            String txet = null;
//            while ((txet = keyin.readLine()) != null){
//                ps.println(txet);
//            }

        }catch (IOException e){
            System.out.println("网络出错 请重新登录");
        }finally {
            try{
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
}
class MyServer{
    public static void main(String[] args){
        //创建ServerSocket
        try(ServerSocket serverSocket = new ServerSocket(8888)){
            //监听客服端的连接
            Socket clientSocket = serverSocket.accept();

            //从终端接收数据
            BufferedReader keyin = new BufferedReader(new InputStreamReader(System.in));
            //获取向客户端的输出数据的输出流
            PrintStream ps = new PrintStream(clientSocket.getOutputStream());
            String line = null;
            while ((line = keyin.readLine()) != null){
                //发送给客户端
                ps.println(line);
            }

//            //接收客户端的数据
//            BufferedReader br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
//            String text = null;
//            while ((text = br.readLine()) != null){
//                System.out.println(text);
//            }

        }catch (IOException e){
            e.printStackTrace();
        }


    }
}

(3) * 客户端向服务器端发送图片 post上传

class Client1{
    public static void main(String[] args) throws IOException {
        //连接服务器 获取socket
        Socket socket = new Socket("192.168.43.117", 9999);

        //创建服务器端对应的输入流 用于接收服务器端发来的数据
        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        System.out.println(br.readLine());

        //向服务器端发送文件(图片)
        //1.将文件写入内存里面
        String path = "C:\\Users\\DELL\\Desktop\\1.png";
        FileInputStream fis = new FileInputStream(path);

//        //2,将内容输出到服务器端
//        PrintStream ps= new PrintStream(socket.getOutputStream());
//
//        //3.将文件的内容一点一点地传送给服务器
//        byte[] buf = new byte[1024];
//        int len = -1;
//        while ((len = fis.read(buf)) != -1){
//            ps.println(new String(buf,0,len));
//        }

        //2.创建字节流 outputStream
        BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
        byte[] buf = new byte[1024];
        int len = -1;
        while ((len = fis.read(buf)) != -1){
            bos.write(buf,0,len);
        }
        socket.shutdownOutput();

    }
}
class Server1{
    public static void main(String[] args) throws IOException {
        //创建服务器端的ServerSocket
        ServerSocket ss = new ServerSocket(9999);

        //监听客户端链接
        //当有客户端来连接这个服务器 就可以得到对应的socket
        //当没有客户端连接 服务器一直在这里等待
        Socket socket = ss.accept();

        //创建客户端对应的输出流 用于向这个客户端发送数据
        PrintStream ps = new PrintStream(socket.getOutputStream());
        ps.println("连接成功 可以发送数据!");

//        //接收客户端传递过来的图片
//        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//
//        //文件对应的输出流
//        String path = "E:\\JavaStudy\\JavaXuexi\\src\\main\\java\\day12\\2.png";
//        PrintStream psFile = new PrintStream(new FileOutputStream(path));
//
//        String line = null;
//        char[] buf = new char[1024];
//        int len = -1;
//        while ((len = br.read(buf)) != -1){
//            //将字符数组转化为字符串
//            line = new String(buf,0,len);
//            //将字符串写入到文件
//            psFile.println(line);

        BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
        String path = "E:\\JavaStudy\\JavaXuexi\\src\\main\\java\\day12\\2.png";
        FileOutputStream fos = new FileOutputStream(path);

        byte[] buf = new byte[1024];
        int len = -1;
        while((len = bis.read(buf)) != -1){
            fos.write(buf,0,len);

        }
    }
}

(4) 服务器端与客户端 对聊

  • 客户端好服务器端都可以随意地发送内容
  • 从终端输入
  • 客户端:
    主线程:接收终端输入 将终端输入发送给服务器端
    子线程:接收服务器端发过来的数据
    服务器端:
    主线程:接收终端输入 将1终端输入发送给客户端
    子线程:接收客户端发过来的数据
定义Clinet,Server类主线程:
class Client {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket("192.168.43.117", 8888);
        //子线程 处理服务端数据
        new Thread(new ClientThread(socket)).start();

        BufferedReader keyin = new BufferedReader(new InputStreamReader(System.in));
        //客户端的输出流对象
        PrintStream printStream = new PrintStream(socket.getOutputStream());
        String line = null;
        while ((line = keyin.readLine()) != null) {
            printStream.println(line);
        }


    }
}
class Server{
    public static void main(String[] args) throws IOException {
        ServerSocket ss = new ServerSocket(8888);
        //获取客户端的socket
        Socket socket = ss.accept();

        //创建子线程 处理客户端的输入信息
        new ServerThread(socket).start();

        //终端输入流对象
        BufferedReader keyin = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        //客户端的输出流对象
        PrintStream ps = new PrintStream(socket.getOutputStream());
        String line = null;
        while ((line = keyin.readLine()) != null){
            ps.println(line);
        }


    }
}
实现子线程,用于接收服务器端或客户端的数据:
/**
 * 创建子线程处理客户端接收服务器端的数据
 */
class ClientThread implements Runnable{
    private Socket socket;
    //保存操作的socket 对象
    public ClientThread(Socket socket){
        this.socket = socket;
    }
    @Override
    public void run() {
        BufferedReader bufferedReader = null;
        try {
            //获取输入
            bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            //读取
            String line = null;
            while ((line = bufferedReader.readLine()) != null){
                System.out.println(line);
            }
        } catch (IOException e) {
            System.out.println("网络出错  请重新登录");
            System.exit(-1);
        }finally {
            try {
                if (bufferedReader != null) {
                    bufferedReader.close();
                }
                if (socket != null) {
                    socket.close();
                }
            }catch (IOException e) {
                e.printStackTrace();
            }

        }
    }
}
/**
 * 创建一个子线程处理服务器端接收客户端的数据
 */
class ServerThread extends Thread{
    private Socket socket;

    public ServerThread(Socket socket){
        this.socket = socket;
    }

    @Override
    public void run() {
        BufferedReader br = null;
        try {
             br = new BufferedReader(new InputStreamReader(socket.getInputStream()));

            //读取数据
            String line = null;
            while ((line = br.readLine()) != null){
                System.out.println(line);
            }
        } catch (IOException e) {
            System.out.println("网络异常 请重新登录");
            System.exit(-1);
        }finally {
            //
            //
            try{
                if(br != null){
                    br.close();
                }
                if(socket != null){
                    socket.close();
                }
            }catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

5..如何实现群聊

重点思想:在服务器端维护一个数组(socket)

实现服务器端:
class Server{
    //保存每一个来连接的socket对象
    public static ArrayList sockets = new ArrayList<>();
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(9999);

        //不停地等待客户端来连接
        while (true){
            Socket socket = serverSocket.accept();
            //保存每一个客户端socket
            sockets.add(socket);

            //开启一个线程处理每一个客户端的输出
            new ServerThread(socket).start();
        }
    }
}
实现Server接收每个客户端数据传输:
/**
 * 创建一个子线程处理服务器端接收客户端的数据
 */
class ServerThread extends Thread{
    private Socket socket;

    public ServerThread(Socket socket){
        this.socket = socket;
    }

    @Override
    public void run() {
        BufferedReader br = null;

        try {
            br = new BufferedReader(new InputStreamReader(socket.getInputStream()));

            //读取数据
            String line = null;
            while ((line = br.readLine()) != null){
                //群发消息
                //遍历Socket维护的数组
                for(Socket s : Server.sockets){
                    //向socket对应的客户端发送消息
                    PrintStream ps = new PrintStream(s.getOutputStream());
                    ps.println(line);
                }
            }
        } catch (IOException e) {
            System.out.println("网络异常 请重新登录");
            System.exit(-1);
        }finally {
            //
            //
            try{
                if(br != null){
                    br.close();
                }
                if(socket != null){
                    socket.close();
                }
            }catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
客户端实现与对聊的代码一样:
class Client{
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket("10.129.28.253",6666);

        //用一个子线程处理服务器端数据
        new Thread(new ClientThread(socket)).start();

        //主线程处理终端输入 发送给服务器端
        BufferedReader keyin = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        PrintStream ps = new PrintStream(socket.getOutputStream());
        String line = null;
        while ((line = keyin.readLine()) != null){
            ps.println(line);
        }

    }
}

/**
 * 创建子线程处理客户端接收服务器端的数据
 */
class ClientThread implements Runnable{
    private Socket socket;

    public ClientThread(Socket socket){
        this.socket = socket;
    }
    @Override
    public void run() {
        BufferedReader br = null;
        try {
            //获取服务器端的输入流对象
            br = new BufferedReader(new InputStreamReader(socket.getInputStream()));

            //读取数据
            String line = null;
            while ((line = br.readLine()) != null){
                System.out.println(line);
            }
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            try{
                if(br != null){
                    br.close();
                }
                if(socket != null){
                    socket.close();
                }
            }catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

心得:

今天循环写差不多的代码。头都搞晕了,晚自习时是在没精神啊,但效果真的不错,复习时轻轻松松,因为都有印象。

你可能感兴趣的:(网络编程2019-08-21)