美文网首页
[Java]开发安卓,你得掌握的Java知识13——网络基础

[Java]开发安卓,你得掌握的Java知识13——网络基础

作者: 入梦瞌睡 | 来源:发表于2019-08-21 23:26 被阅读0次

    0.前言

    • 今天我们主要讲解一些网络基本概念

    • 这篇文章内容可能有点水,某些原因导致头昏脑胀,已经好几次差点昏过去了,但是还是得坚持写完,请大家多多谅解

    • 若想要了解“类”等其他主要知识,可以去看前面的文章

    • 由于最终目的是要开发安卓app,
      因此这里使用的IDE是AS(Android Studio)
      (不会使用的可以参考下面这篇文章中的例子)
      [Java]开发安卓,你得掌握的Java知识2

    1.文章主要内容

    • 网络的基本概念简单讲解

    • 用AS完成简单的服务器端与客户端的交互


    2.基础知识讲解

    网络相关概念简介

    • URL:
      统一的资源定位,用于找服务器中的某个资源

    • http/https:
      超文本传输协议(HyperText Transfer Protocol)
      一种传输时候需要遵循的协议

    • TCP/IP协议
      它是传输层协议,主要解决数据如何在网络中传输,
      而HTTP是应用层协议,主要解决如何包装数据。

    • DNS服务器:
      域名解析,将"www.baidu.com"类型的域名解析为对应的ip地址

    • ip地址
      某台电脑的ip地址,能找到这台网络中该电脑的位置

    • 端口号:
      端口号就是用来标识这台电脑上的某个进程
      比如QQ的端口号为1
      依靠电脑的ip地址和端口号1,就可以访问这台电脑的QQ

    客户端与服务器.png
    • 套接字(socket)
      是一个抽象层,应用程序可以通过它发送或接收数据
      客户端用的是Socket类,而服务器端用的是ServerSocket类

    客户端方面:

    Socket类的方法 具体描述
    getInputStream 得到一个输入流,即得到从服务器端发回的数据。
    getOutputStream 得到一个输出流,即得到发送给服务器端的数据。

    服务器端端方面:

    Socket类的方法 具体描述
    getInputStream 得到从客户端发送给服务器端的数据流。
    getOutputStream 得到发送给客户端的数据。

    3.服务器端与客户端的简单交互

    第一步

    在MyClient中创建一个主函数,并且在主函数中创建客户端Socket类对象
    构造方法中,第一个参数是欲访问的ip地址,第二个参数是欲访问的端口

    public class MyClient{
           public static void main(String[] args){
                  Socket socket = new Socket("127.0.0.1",9090);
           }  
    }
    

    第二步

    在MyServer中创建一个主函数,并且在主函数中创建客户端ServerSocket类对象
    构造方法中,参数是服务器端开放的端口

    public class MyServer{
           public static void main(String[] args){
                  ServerSocket ss = new ServerSocket(9090);
                  Socket socket = ss.accept();
           }  
    }
    

    第三步

    写一个MessageManager类,里面写两个函数:
    getTerminalMessageAndSent(Socket socket)

    getMessageFromOppsite(Socket socket)

    public void getTerminalMessageAndSent(Socket socket) throws IOException {
            BufferedReader keyIn = new BufferedReader(new InputStreamReader(System.in));
            String line = null;
            PrintStream ps = new PrintStream(socket.getOutputStream());
            while ((line = keyIn.readLine()) != null) {
                ps.println(line);
            }
            ps.close();
            keyIn.close();
        }
    
    • 注意:
      (1)BufferedReader的构造方法中需要一个Reader,因此,使用new InputStreamReader()将字节流转成字符流
      (2)这个函数主要功能是:获得终端输入的信息并且输出给对面
      (3)PrintStream的作用就是通过print()或者println()将内容输出给对方
      (4)line = keyIn.readLine()意思是将终端输入的内容赋值给line,然后用ps.println输出
      (5)socket.getOutputStream()表示得到想要发送出去的数据
     public void getMessageFromOppsite(Socket socket){
            try {
                BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                String line = null;
                while ((line = br.readLine()) != null) {
                    System.out.println(line);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
    • 注意:
      (1)BufferedReader是用来接收传过来的信息的,所以后面用的是socket.getInputStream(),即获得传入的数据
      (2)new InputStreamReader可以将InputStream转换为Reader,以此来初始化BufferedReader
      (3)line = br.readLine(),可以将读到的内容赋值给line,然后使用System.out.println()输出
      (4)可以使用readLine()的理由是:上面第一个函数中用的是println()

    第四步

    创建一个Client类,里面写一个静态的socket

    public Client{
        public static Socket socket;
        static {
            try {
                socket = new Socket("127.0.0.1",9090);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    

    创建一个,Server类,同上

    public class Server {
        public static ServerSocket serverSocket;
        public static Socket socket;
    static {
            try {
                serverSocket = new ServerSocket(9090);
                socket = serverSocket.accept();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    

    第五步

    为Client写两个类,这两个类实现了Runnable接口,即可以放在不同的线程中,以此实现服务端与客户端的实时交互

    public class ClientGet implements Runnable{
    
        @Override
        public void run() {
            MessageManager.instance.getMessageFromOppsite(Client.socket);
            ClientManager.countNow++;
            //super.run();
        }
    }
    
    
    public class ClientSent implements Runnable{
        @Override
        public void run() {
            try {
                MessageManager.instance.getTerminalMessageAndSent(Client.socket);
                ClientManager.countNow++;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    

    为Server类同理

    public class ServerGet implements Runnable{
    
        @Override
        public void run() {
            try {
             MessageManager.instance.getMessageFromOppsite(Server.socket);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
    
    public class ServerSent implements Runnable{
        @Override
        public void run() {
            try {
            MessageManager.instance.getMessageFromOppsite(Server.socket);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
    

    第六步

    在MyClient中实现两个子线程,MyServer中同理

    public class MyClient {
        public static void main(String[] args) {
            ClientGet cg = new ClientGet();
            ClientSent ct = new ClientSent();
    
            Thread t = new Thread(cg);
            Thread t2 = new Thread(ct);
    
            t.start();
            t2.start();
        }
    }
    
    public class MyServer {
        public static void main(String[] args) {
            ServerGet sg = new ServerGet();
            ServerSent ss = new ServerSent();
    
            Thread t = new Thread(sg);
            Thread t2 = new Thread(ss);
    
            t.start();
            t2.start();
        }
    }
    

    最后

    先开启MyServer中的main函数,再开启MyClient的,然后,就可以在终端进行交互了,在MyServer的终端输入的内容,可以在MyClient中看到,反之亦然。

    4.总结

    (1)本文讲解一些网络的简单概念,以及服务器端和客户端的交互相关知识
    (2)其实服务器端和客户端交互的基础逻辑概念并不难理解,关键还是在于各种输入流和输出流的运用,必须搞清楚什么时候该用哪种流
    (3)只有多练习,才能熟练整个交互过程,为日后安卓开发打下良好的基础

    相关文章

      网友评论

          本文标题:[Java]开发安卓,你得掌握的Java知识13——网络基础

          本文链接:https://www.haomeiwen.com/subject/zhaisctx.html