Socket 使用心得总结

Socket 有什么用?

  1. Socket 是进程间通信的一种常用方式
  2. Windows – Linux – Android 各系统之间高效交互

Socket 代码书写刚开始接触会有点儿难理解,我觉得首先要对Socket有一个全局的认识:

  1. 通信的关键在于获得一个 socket 对象,获得这个对象就相当于建立了一个长连接,只有某一方主动断开连接,这个长连接才会断开;
  2. 一个端口可以有多个链接存在,看下图
    socket示意图
    从上图可以看出,不仅多个客户端可以和服务端的一个端口建立多个连接,并且一个客户端也可以和服务端的一个端口建立多个连接;
    所以说 Socket 一个端口可以并行的做不同的事情;

知道了这些之后我们就要开始码代码了,为了便于理解,我将socket 的代码分成了几个模块
服务端:
1、开启监听,等待连接
2、得到 socket 对象,开始交互
3、断开连接
客户端:
1、连接服务端
2、得到 socket 对象,开始交互
3、断开连接
这个过程中我们需要注意的是:

我们先从服务端来看:

1、开启监听,等待连接,得到socket对象

        new Thread(new Runnable() {
            @Override
            public void run() {
                if(serverSocket==null){
                    try {
                        serverSocket = new ServerSocket(3060);
                    } catch (IOException e) {
                        e.printStackTrace();
                        Log.d(TAG,"fail to new serversocket");
                    }
                }
                try {
                    Log.d(TAG,"作为服务端:我们开始监听!!");
                    mSocket = serverSocket.accept();// 这是一个阻塞方法
                    Log.d(TAG,"作为服务端被连接:有设备连接到了我们!!");
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();

这段代码注意 serverSocket.accept() 是一段阻塞代码(耗时操作),它的返回值就是我们第二步需要的 socket对象。
将得到的 socket 的对象保存之后,我们就可以继续监听其它的连接了;
2、交互和断开连接
– 获得输入输出流,为交互做准备

private void onConnectSucceed(){
        try {
            inputStream = mSocket.getInputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            outputStream = mSocket.getOutputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
        //stopListening();
        startListeningMessage();
    }

– 监听客户端的消息

public void startListeningMessage() {
        listenThread = new Thread(new Runnable() {
            @Override
            public void run() {
                inputStreamReader = new InputStreamReader(inputStream);//提高效率,将自己字节流转为字符流
                bufferedReader = new BufferedReader(inputStreamReader);//加入缓冲区String temp=null;
                String info = "";
                String temp = "";
                //Log.d(TAG,"服务端检测客户端消息:当前客户端ip为:"+mSocket.getInetAddress().getHostAddress());
                try {
                    while ((temp = bufferedReader.readLine()) != null) {
                    	// 当对方主动断开连接,才会跳出while 循环
                        info += temp;
                        Log.d(TAG, "服务端接收到客户端信息:" + info + ",当前客户端ip为:" + mSocket.getInetAddress().getHostAddress());
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                    //Log.d(TAG,"服务端监听消息出错:当前客户端ip为:"+mSocket.getInetAddress().getHostAddress());
                }
                onSocketClosed();//跳出循环,意味着这个socket 连接断开,我们需要将一些不需要的数据释放掉
                Log.d(TAG, "服务端监听消息结束!!");
            }
        });
        listenThread.start();
    }

– 向客户端发送数据

 new Thread(new Runnable() {
            @Override
            public void run() {
                if (outputStream != null) {
                    try {
                        writer = new DataOutputStream(outputStream);
                        writer.writeUTF(msg + " \n");  // 写一个UTF-8的信息
                        writer.flush();
                    } catch (IOException e) {
                        e.printStackTrace();
                        // 发送消息失败
                    }
                }
            }
  }).start();

再看一下客户端

客户端与服务端不同的地方只在于,服务端是监听端口,等待客户端来连接
而客户端就是直接连接就可以了

 new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    sendMegForToast("msg", "作为客户端:我们尝试连接!!");
                    mSocket = new Socket("192.168.100.153", 3060);// 这也是一个耗时操作
                    Log.d(TAG, "作为客户端连接成功!");
                    sendMegForToast("msg", "作为客户端连接成功!");
                    onConnectSucceed();
                } catch (IOException e) {
                    e.printStackTrace();
                    Log.d(TAG, "作为客户端尝试连接失败!");
                    sendMegForToast("msg", "作为客户端尝试连接失败!");
                }
            }
        }).start();

其中
mSocket = new Socket(“192.168.100.153”, 3060);
这段代码也是阻塞的,一段耗时操作,当连接成功之后才会向下执行;
其它部分和服务端完全一致

socket 这个东西,理解基本的用法,明白它的一些关键点,多去把它嵌套到实际的工作任务中,就可以得心应手的使用它了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值