【精华】Android面试精华总结——Socket网络通信

一、Android网络通信基础

1.网络通信简介

  Android完全支持JDK本身的TCP、UDP网络通信API,也可使用ServerSocket、Socket来建立基于TCP/IP协议的网络通信,还可使用DatagramSocket、Datagrampacket、MulticastSocket来建立基于UDP协议的网络通信。Android也支持JDK提供的URL、URLConnection等网络通信API。

2.套接字Socket

【精华】Android面试精华总结——Socket网络通信_第1张图片
  Socket是对TCP/IP协议的封装,是一个调用接口API。在TCP/IP协议中主要有Socket类型的流套接字StreamSocket和数据报套接字DatagramSocket。

  • 流套接字将TCP作为其端到端的协议,提供一个可信赖的字节流服务。
  • 数据报套接字使用UDP协议,提供数据打包发送服务。

【精华】Android面试精华总结——Socket网络通信_第2张图片
套接字通信的使用步骤:

  1. 创建ServerSocket和Socket
  2. 打开连接到的Socket的输入/输出流
  3. 按照协议对Socket进行读/写操作
  4. 关闭输入输出流,以及Socket

二、基于TCP协议的网络通信

1.使用ServerSocket创建TCP服务器端

  Java中能接受其他通信实体连接请求的类是ServerSocket,ServerSocket对象用于监听来自客户端拿到Socket连接,如果没有连接,它将一直处于等待状态。

ServerSocket ss =new ServerSocket(30000);
while(true){
	Socket s = ss.accept();
	……
} 

  使用步骤:

  1. 创建ServerSocket对象,绑定监听的端口;
  2. 调用accept()方法监听客户端的请求;
  3. 连接建立后,通过输入流InputStream读取接收到的数据;
  4. 通过输出流OutputStream向客户端发送响应信息;
  5. 调用close()方法关闭相关资源。
public class SocketServer {
    public static void main(String[] args) throws IOException {
        //1.创建一个服务器端Socket,即ServerSocket,指定绑定的端口,并监听此端口
        ServerSocket serverSocket = new ServerSocket(12345);
        InetAddress address = InetAddress.getLocalHost();
        String ip = address.getHostAddress();
        Socket socket = null;
        //2.调用accept()等待客户端连接
        System.out.println("~~~服务端已就绪,等待客户端接入~,服务端ip地址: " + ip);
        socket = serverSocket.accept();
        //3.连接后获取输入流,读取客户端信息
        InputStream is=null;
        InputStreamReader isr=null;
        BufferedReader br=null;
        OutputStream os=null;
        PrintWriter pw=null;
        is = socket.getInputStream();     //获取输入流
        isr = new InputStreamReader(is,"UTF-8");
        br = new BufferedReader(isr);
        String info = null;
        while((info=br.readLine())!=null){
        	//循环读取客户端的信息
            System.out.println("客户端发送过来的信息" + info);
        }
        socket.shutdownInput();//关闭输入流
        socket.close();
    }
}

2.使用Socket创建TCP客户端

  构造器中指定远程主机时既可使用InetAddress来指定,也可直接使用String对象来指定,但程序通常使用String对象来指定远程IP地址。

Socket s = new Socket("192.168.1.88",30000); 

  使用步骤:

  1. 创建Socket对象,指明需要连接的服务器的IP地址和端口号;
  2. 连接建立后,通过输出流OutputStream向服务器发送请求信息;
  3. 通过输入流InputStream获取服务器响应的信息;
  4. 调用close()方法关闭套接字。
public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button btn_accept = (Button) findViewById(R.id.btn_accept);
        btn_accept.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        new Thread() {
            @Override
            public void run() {
                try {
                    acceptServer();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }.start();
    }

    private void acceptServer() throws IOException {
        //1.创建客户端Socket,指定服务器地址和端口
        Socket socket = new Socket("172.16.2.54", 12345);
        //2.获取输出流,向服务器端发送信息
        OutputStream os = socket.getOutputStream();//字节输出流
        PrintWriter pw = new PrintWriter(os);//将输出流包装为打印流
        //获取客户端的IP地址
        InetAddress address = InetAddress.getLocalHost();
        String ip = address.getHostAddress();
        pw.write("客户端:~" + ip + "~ 接入服务器!!");
        pw.flush();
        socket.shutdownOutput();//关闭输出流
        socket.close();
    }}
}}

  注:Android已经不允许在UI线程中建立网络连接。

  在Android中访问互联网,要为该应用赋予访问互联网的权限:
  

三、基于UDP协议的网络通信

  UDP以数据报作为数据的传输载体,在进行传输时首先要把传输的数据定义成数据报(Datagram),在数据报中指明数据要到达的Socket(主机IP地址和端口号),然后再将数据以数据报的形式发送出去。

1.创建UDP服务器端

  使用步骤:

  1. 创建DatagramSocket对象,指定端口号;
  2. 创建DatagramPacket对象,用于接收客户端发送的数据;
  3. 调用DatagramSocket的receiver()方法接收信息;
  4. 读取数据。
  5. 调用DatagramSocket的close()方法关闭资源。
public class UPDServer {
    public static void main(String[] args) throws IOException {
        /*
         * 接收客户端发送的数据
         */
        // 1.创建服务器端DatagramSocket,指定端口
        DatagramSocket socket = new DatagramSocket(12345);
        // 2.创建数据报,用于接收客户端发送的数据
        byte[] data = new byte[1024];// 创建字节数组,指定接收的数据包的大小
        DatagramPacket packet = new DatagramPacket(data, data.length);
        // 3.接收客户端发送的数据
        System.out.println("****服务器端已经启动,等待客户端发送数据");
        socket.receive(packet);// 此方法在接收到数据报之前会一直阻塞
        // 4.读取数据
        String info = new String(data, 0, packet.getLength());
        System.out.println("我是服务器,客户端说:" + info);

        /*
         * 向客户端响应数据
         */
        // 1.定义客户端的地址、端口号、数据
        InetAddress address = packet.getAddress();
        int port = packet.getPort();
        byte[] data2 = "欢迎您!".getBytes();
        // 2.创建数据报,包含响应的数据信息
        DatagramPacket packet2 = new DatagramPacket(data2, data2.length, address, port);
        // 3.响应客户端
        socket.send(packet2);
        // 4.关闭资源
        socket.close();
    }
}

2. 创建UDP客户端

  使用步骤:

  1. 创建InetAddress对象等,定义要发送的信息;
  2. 创建DatagramPacket对象,包含将要发送的信息;
  3. 创建DatagramSocket对象;
  4. 调用DatagramSocket对象的send()方法发送数据。
  5. 调用DatagramSocket对象的close()方法关闭资源。
public class UDPClient {
    public static void main(String[] args) throws IOException {
        /*
         * 向服务器端发送数据
         */
        // 1.定义服务器的地址、端口号、数据
        InetAddress address = InetAddress.getByName("localhost");
        int port = 8800;
        byte[] data = "用户名:admin;密码:123".getBytes();
        // 2.创建数据报,包含发送的数据信息
        DatagramPacket packet = new DatagramPacket(data, data.length, address, port);
        // 3.创建DatagramSocket对象
        DatagramSocket socket = new DatagramSocket();
        // 4.向服务器端发送数据报
        socket.send(packet);

        /*
         * 接收服务器端响应的数据
         */
        // 1.创建数据报,用于接收服务器端响应的数据
        byte[] data2 = new byte[1024];
        DatagramPacket packet2 = new DatagramPacket(data2, data2.length);
        // 2.接收服务器响应的数据
        socket.receive(packet2);
        // 3.读取数据
        String reply = new String(data2, 0, packet2.getLength());
        System.out.println("我是客户端,服务器说:" + reply);
        // 4.关闭资源
        socket.close();
    }
}

你可能感兴趣的:(Android开发)