Android Socket通信(一) -- 初识与相遇

系列文章:
Android Socket 系列更新计划
Android Socket通信(一) – 初识与相遇
Android Socket通信(二) --UDP,单播,广播和多播(组播)
Android Socket通信(三) – TCP 配置和传递基础数据
Android Socket通信(四) – UDP与TCP结合传输数据
Android Socket通信(五) – 实现一个多人聊天室

工程连接 : https://github.com/LillteZheng/SocketDemo

在万物互联的时代,学习 socket 可以加深我们对网络的理解,并写出自己的IM或及时通信,废话不多说,接着开始我们得 socket 之旅吧。
通过这边文章你将学习到:

  • 学习 socket
  • 了解socekt通信的通用步骤
  • 一个简单的聊天实例

一、认识 Socket

socket 是端对端的通信,即网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket;
那两台计算机怎么通信呢 ? 它的通信必要条件为:IP地址,协议,端口号

  • IP地址:两台主机他们需要有一个唯一的标识,用来表示他们所处的身份,所在的位置,这就是IP地址
  • 协议:需要有共同的语言,否则就会出现言语不通,无法交流,这就是我们的协议,比如 TCP/IP协议簇
  • 端口号:每台主机都需要有相应的端口号,一台主机上可以运行多个应用程序,那如何辨别不同应用程序的通信,我们需要使用端口号来进行区分。

而 socket 通信是基于TCP/IP 网络层上的一种传送方式,我们通常把TCP和UDP称为传输层(图片来源百度图片):在这里插入图片描述

socket 是对TCP/IP的一层抽象,即对传输层的一系列的封装,供开发者去使用,而不用去理解整个网络传输的复杂过程;

二、建立socket 的步骤

在建立 socket ,我们需要分别创建 server 和 client ,用一张图来解释可以如下 (图片来源百度图片):
在这里插入图片描述
从上图我们得出 服务端的步骤:

  1. 获取 ServerSocket 的实例
  2. 通过 server.accpet() 拿到客户端的 socket 实例
  3. 通过 socket.getInputStream() 或 socket.getOutputStream() 进行数据传输

客户端步骤:

  1. 获取 Socket 的实例
  2. 通过 connect 连接服务器
  3. 通过 socket.getInputStream() 或 socket.getOutputStream() 进行数据传输

三、实例

理解了上面的连接过程,接着,我们来实现一个简单栗子;
即,客户端通过终端数据,并发送给服务端,服务端拿到数据后,回数据给客户端,以 ‘bye’ 结束
首先先看 客户端代码,首先通过 System.in 拿到终端的数据,然后通过 outputstream 发送给客户端,如下:

/**
 * created by zhengshaorui
 * time on 2019/6/18
 * socket 客户端,从控制台获取信息,发送给服务器端,然后
 * 获取服务端的信息并显示
 */
public class Client {
    public static void main(String[] args) {

        try {
            //1.拿到socket实例
            Socket socket = new Socket();
            //超时时间
            socket.setSoTimeout(3000);
            //连接本地,端口8000,超时时间为3s
            // 2. 通过 connect连接服务器
            socket.connect(new InetSocketAddress(Inet4Address.getLocalHost(),8000),3000);
            //打印基本信息
            System.out.println("客服端信息: "+socket.getLocalAddress()+" 端口: "+socket.getLocalPort());
            System.out.println("服务端信息: "+socket.getInetAddress()+" 端口: "+socket.getPort());

            //获取终端输入流
            BufferedReader cmdReader = new BufferedReader(new InputStreamReader(System.in));
            //3.拿到 inputstream 或者 outputstream 进行通信
            PrintStream clientPrintStream = new PrintStream(socket.getOutputStream());
            BufferedReader clientReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            
            //让它可以循环打印
            boolean flag = true;
            do {
                //获取终端数据,发送给服务器
                String msg = cmdReader.readLine();
                clientPrintStream.println(msg);

                //从服务器读数据
                String echo = clientReader.readLine();
                if ("bye".equalsIgnoreCase(echo)){
                    flag = false;
                }else{
                    System.out.println(echo);
                }


            }while (flag);

            //资源释放
            cmdReader.close();
            clientReader.close();
            //socket.close();
            System.out.println("我已断开连接");

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

接着看服务端代码:

/**
 * created by zhengshaorui
 * time on 2019/6/18
 * socket 的服务端,拿到客户端信息后,返回客户端信息的长度
 */
public class Server {
    public static void main(String[] args) {


        try {
            //1.获取 serversocket 实例
            ServerSocket serverSocket = new ServerSocket(8000);
            System.out.println("服务器准备就绪~");
            System.out.println("服务器信息:" + serverSocket.getInetAddress() + " P:" + serverSocket.getLocalPort());
            //开始阻塞接受客户端
            //2.通过 accept 拿到 客户端的socket
            Socket socket = serverSocket.accept();
            handleClient handleClient = new handleClient(socket);
            handleClient.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    static class handleClient  extends Thread{

        private Socket socket;
        private boolean flag = true;
        public handleClient(Socket socket) {
            this.socket = socket;
        }

        @Override
        public void run() {
            super.run();
            try {
                System.out.println("新的客户端连接了: "+socket.getInetAddress()+" 端口: "+socket.getPort());
                //3.通过 inputstream 或 outputstream 进行数据传递
                PrintStream printStream = new PrintStream(socket.getOutputStream());
                BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                do {
                    String msg = br.readLine();
                    if ("bye".equalsIgnoreCase(msg)){
                        flag = false;
                        printStream.println("bye");
                    }else{
                        System.out.println("客户端信息: "+msg);
                        printStream.println("信息长度: "+msg.length());
                    }
                }while (flag);

                //释放资源
                br.close();

            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                try {
                    socket.close();

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

            }
            System.out.println("客户端: "+socket.getInetAddress()+" 断开连接了");
        }
    }
}

效果如下 (记得先启动服务端再启动客户端端):
服务端:
在这里插入图片描述
客户端:
在这里插入图片描述

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值